1. ホーム
  2. python

[解決済み] Pythonオブジェクトのコピー/ディープコピー操作をオーバーライドするには?

2022-09-03 15:23:45

質問

の違いについて理解しています。 copy vs. deepcopy をコピーモジュールで使用します。私はこれまで copy.copycopy.deepcopy をオーバーロードするのは初めてです。 __copy____deepcopy__ というメソッドがあります。 私はすでにググって、組み込みのPythonモジュールに目を通した上で __copy____deepcopy__ 関数(例えば sets.py , decimal.py そして fractions.py ) を使っていますが、まだ100%正しいとは言えません。

これが私のシナリオです。

設定オブジェクトがあります。 最初は、デフォルトの値のセットを持つ1つの設定オブジェクトをインスタンス化するつもりです。 この構成は、他の複数のオブジェクトに渡されます (すべてのオブジェクトが同じ構成で開始されるようにするため)。 しかし、ユーザーとの対話が始まると、各オブジェクトは互いの構成に影響を与えることなく、独立して構成を調整する必要があります(つまり、私の初期構成のディープコピーを作成して渡す必要がある、ということです)。

ここにサンプルオブジェクトがあります。

class ChartConfig(object):

    def __init__(self):

        #Drawing properties (Booleans/strings)
        self.antialiased = None
        self.plot_style = None
        self.plot_title = None
        self.autoscale = None

        #X axis properties (strings/ints)
        self.xaxis_title = None
        self.xaxis_tick_rotation = None
        self.xaxis_tick_align = None

        #Y axis properties (strings/ints)
        self.yaxis_title = None
        self.yaxis_tick_rotation = None
        self.yaxis_tick_align = None

        #A list of non-primitive objects
        self.trace_configs = []

    def __copy__(self):
        pass

    def __deepcopy__(self, memo):
        pass 

を実装する正しい方法は何でしょうか? copydeepcopy メソッドを使用して、このオブジェクトの copy.copycopy.deepcopy は、私に適切な動作を与えますか?

どのように解決するのですか?

カスタマイズのための推奨事項は、一番最後にある ドキュメント・ページ :

クラスは、コピー制御のために使用するのと同じインターフェイスを コピーを制御するために使用されるのと同じ ピックリングを制御するのと同じインターフェイスを使うことができます。pickleモジュールの説明を見てください。 モジュール pickle の説明を参照してください。 を参照してください。コピーモジュールは 登録モジュール copy_reg を使用しません。 モジュールを使用します。

クラスが独自の コピーの実装を定義するために、そのクラスは 特別なメソッド __copy__()__deepcopy__() . 前者は浅いコピー操作を実装するために呼ばれます。 操作を実装するために呼び出されます。 は渡されません。後者は,ディープコピー操作を実装するために呼び出されます。 ディープコピー操作を実装するために呼び出される。 は1つの引数、メモ 辞書が渡される。もし __deepcopy__() 実装がコンポーネントの深いコピーを作成する必要がある場合 コンポーネントのディープコピーを作成する必要がある場合、それは を呼び出します。 deepcopy() 関数を呼び出します。 コンポーネントを第一引数として メモ辞書を第2引数にとります。

カスタマイズのピックリングには関心がないようなので、以下のように定義します。 __copy____deepcopy__ が間違いなくあなたに合った方法だと思われます。

具体的には __copy__ (浅いコピー)は、あなたの場合、かなり簡単だと思いますが...。

def __copy__(self):
  newone = type(self)()
  newone.__dict__.update(self.__dict__)
  return newone

__deepcopy__ も同様です。 memo の引数も受け取る) が、リターンの前に self.foo = deepcopy(self.foo, memo) を呼び出さなければなりません。 self.foo を通して他のものを保持するリスト、ディクショ ン、非プリミティブオブジェクトなどのコンテナである属性は、深いコピー が必要です。 __dict__ s).