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

我认为这是最 Pythonic 的方式 - 复制工厂方法。

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

dict.copy这在 python 基本类型(例如)中相当普遍。它不是一个复制构造函数,但我不认为这是一个非常 Pythonic 的概念!

于 2012-05-17T17:52:38.287 回答
0

这是可能的,因为您可以遍历传递给的源对象上的所有属性__init__,然后遍历setattr()您关心的那些self。但目前还不清楚这是否是解决问题的好方法。不是很Pythonic,和所有。

于 2012-05-17T17:54:07.927 回答
0

做到这一点的一种好方法是制作实例名称空间的顶级副本。

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 回答