0

self実行中に渡された元のコピーを使用してメソッドを実行したい。

これが私が話しているコードです:

def protect_self(func):
    from copy import copy
    from functools import wraps
    @wraps(func)
    def decorated(self, *args, **kwargs):
        self_copy = copy(self)
        return func(self_copy, *args, **kwargs)
    return decorated

私の理解では、コピー機能は同じタイプの新しいオブジェクトを作成し__dict__、古いオブジェクトを新しいオブジェクトにコピーします(参照を使用するため、実際のオブジェクトインスタンスへの変更__dict__は元のオブジェクトに影響を与えます)。

__dict__これは、装飾されたメソッドが元のインスタンスを変更できないことを確信できるということですか?

念のため: 安全なサンドボックスの動作は必要ありません。私の目的は、ファクトリとして使用する単一のオブジェクトをインスタンス化することです。保護されたメソッド は、渡されたものを変更できる必要がありselfますが、後でリセットする必要があります。

4

2 に答える 2

2

コピーは、装飾された関数に渡される「自己」がオリジナルの浅いコピーになるようにします。装飾された関数は元の「自己」を直接変更することはできませんが、もちろん他の手段で変更することはできます (間接的にアクセスできる場合)。属性を変更することにより、元の「自己」。

さらに、(任意の) Python コードのどの部分も、プログラム内のほぼすべてのオブジェクトに間接的にアクセスできます。gc装飾された関数は、たとえば、スタック インスペクションまたはモジュールを通じて、元の「自己」にアクセスできます。あなたのユースケースは少し複雑に見えます。これにはクラスインスタンスを使用する必要がありますか?

于 2010-01-22T21:20:26.780 に答える
1

OPがコメントで目的がスレッドセーフであることを明らかにしたように、明らかな問題があります-すでに指摘されている問題に加えて、copy.copyそれ自体はスレッドセーフではありません。それcopy.copy浅いコピーを作成します。self.__dict__変更可能) 変更可能なオブジェクトは完全に変更される可能性があります。これcopy.deepcopyに対処することは (パフォーマンスの点で多額の代償を払う可能性があります)、ある意味ではスレッドセーフの問題をさらに悪化させます (深いコピーは浅いコピーよりもはるかに時間がかかる可能性があるため、競合状態が実際に発生するリスク飛躍的に成長します-私は決して、「まれにしか」発生しない競合状態を持つことを推奨しているわけではありません!-)。

元々安全でないメソッドをスレッドセーフにする必要がある場合は、弾丸をかじってロック (またはキューと補助スレッドを使用して操作をシリアル化する) を使用する必要があります-さらに静かに無視する必要がある場合は、メソッドがオブジェクトを変更しようとすると、さらにdeepcopyすべてを実行する必要があります (たとえば、selfこれらのメソッドがグローバルを変更していたとしたら?!-)。私には非常に不確かな提案に思えます。

于 2010-01-23T03:24:37.477 に答える