14

正確にはこの方法ではありませんが、これと非常によく似た質問がなされていることに気づきました。

クラスのコンストラクターに対してオプションの引数が必要です。これは、クラスのインスタンスである場合はコピーされます。たとえば、(このコードが機能しないことはわかっています!):

class Foo(object):
    def __init__(self, foo=None):
        self.x = None
        self.y = None
        self.z = None

        if foo is not None and isinstance(foo, Foo):
            self = copy.deepcopy(foo)

a = Foo()
a.x = 1
a.y = 2
a.z = 3

b = Foo(a)
print b.x
print b.y
print b.z

これにはいくつかの実用的な解決策があることを私は知っています。fooの対応する属性の値に従って、selfの各属性を設定できますが、私のクラスには非常に多くの属性があるため、これは非常に面倒です。または、単にdoを使用することもできます。

b = copy.deepcopy(a)

...しかし、それが可能であれば、私はむしろしたくありません。また、オーバーライドを避けたいと思っています__new__

コピーコンストラクターを作成するためのPythonの適切な方法は本当にありませんか?

4

3 に答える 3

20

これが最もPython的な方法だと思います-コピーファクトリメソッドです。

import copy

class Foo(object):
    def __init__(self):
        self.x = None
        self.y = None
        self.z = None
    def copy(self):
        return copy.deepcopy(self)

a = Foo()
a.x = 1
a.y = 2
a.z = 3

b = a.copy()
print b.x
print b.y
print b.z

これは、Pythonの基本タイプ(例)ではかなり一般的dict.copyです。これはコピーコンストラクターではありませんが、それは非常にPython的な概念ではないと思います。

于 2012-05-17T17:52:38.287 に答える
0

に渡されたソースオブジェクトのすべての属性を繰り返し処理してから、気になる属性を繰り返し処理できるという点で、可能です。しかし、これが問題を解決するための良い方法であるかどうかはまったく明らかではありません。あまりPythonicではありません。__init__setattr()self

于 2012-05-17T17:54:07.927 に答える
0

これを行う良い方法の1つは、インスタンスの名前空間のトップレベルのコピーを作成することです。

class Tst:
    def __init__(self, somearg):
        if isinstance(somearg, self.__class__):
            self.__dict__ = somearg.__dict__.copy()
        else:
            self.var = somearg
    def echo(self):
        print(self.var)

a = Tst(123)
b = Tst(456)
a.echo()        # gives 123
b.echo()        # gives 456
c = Tst(a)
c.echo()        # gives 123
c.var is a.var  # gives False -> different objects

ただし、クラスがを扱う場合は注意が必要です。__slots__その場合__dict__は欠席する可能性があるため、次のようなより中立的な属性取得メカニズムに依存する必要がある場合があります。getattr()

于 2016-02-10T06:21:35.740 に答える