deepcopy
的 copy
不会复制一个类:
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
这是唯一的方式吗?
B(A):
pass
答案 0 :(得分:38)
一般来说,继承是正确的方法,正如其他海报已经指出的那样。
但是,如果你真的想要使用不同的名称重新创建相同的类型而没有继承,那么你可以这样做:
class B(object):
x = 3
CopyOfB = type('CopyOfB', B.__bases__, dict(B.__dict__))
b = B()
cob = CopyOfB()
print b.x # Prints '3'
print cob.x # Prints '3'
b.x = 2
cob.x = 4
print b.x # Prints '2'
print cob.x # Prints '4'
您必须小心使用可变属性值:
class C(object):
x = []
CopyOfC = type('CopyOfC', C.__bases__, dict(C.__dict__))
c = C()
coc = CopyOfC()
c.x.append(1)
coc.x.append(2)
print c.x # Prints '[1, 2]' (!)
print coc.x # Prints '[1, 2]' (!)
答案 1 :(得分:18)
正如你所推测的那样,“复制”一个类的正确方法是继承:
class B(A):
pass
答案 2 :(得分:8)
您可以使用工厂功能:
def get_A():
class A(object):
ARG = 1
return A
A = get_A()
B = get_A()
答案 3 :(得分:2)
我认为你在这里误解了静态变量的含义。每个在方法之外声明变量而不是self.some_thing
形状的变量,变量都将被视为类的静态变量(就像你的ARG变量一样)。因此,更改静态变量的类的每个对象(实例)都将导致同一类中所有其他对象的更改。深度复制确实在这里完成了工作。
答案 4 :(得分:2)
正如Florian Brucker所指出的,可变类属性存在问题。您也不能只对新样式对象$ tr '_' ' ' < test_file.tsv
mg.reads.per.gene bcsZ A1.tsv contig 21128 476
mg.reads.per.gene bcsZ A1.tsv contig 3712 1774
mg.reads.per.gene bcsZ A2.tsv contig 38480 184
。为了解决这个问题,我已经做了以下工作。我确信有足够的人可以打破这个。但是,它会在更多情况下起作用。
deepcopy(cls.__dict__)
答案 5 :(得分:2)
要复制具有__slots__
属性的类,此功能会有所帮助:-)
def copy_class(c,name=None):
if not name: name = 'CopyOf'+c.__name__
if hasattr(c,'__slots__'):
slots = c.__slots__ if type(c.__slots__) != str else (c.__slots__,)
dict_ = dict()
sloted_members = dict()
for k,v in c.__dict__.items():
if k not in slots:
dict_[k] = v
elif type(v) != types.MemberDescriptorType:
sloted_members[k] = v
CopyOfc = type(name, c.__bases__, dict_)
for k,v in sloted_members.items():
setattr(CopyOfc,k,v)
return CopyOfc
else:
dict_ = dict(c.__dict__)
return type(name, c.__bases__, dict_)
答案 6 :(得分:1)
创建自己的构造函数,并重复创建原始类的方式:
class MyClass(object):
def __init__(self, **kw):
self.kw = kw
self.__dict__.update(kw)
def copy(self):
return MyClass(**self.kw)
我会尽量避免在第一时间复制对象。
旁注:您也可以做到:
B = deepcopy(A)
B.__dict__ = deepcopy(A.__dict__)
但这可能是非常错误的,你不应该这样做。 编辑:实际上AttributeError: 'dictproxy' object has no attribute 'update'
根据OP
答案 7 :(得分:0)
一种简单的方法是将类放入模块中,并在每次需要新副本时重新加载它。我认为这涉及可变项,因为重新加载会重新创建所有内容。
答案 8 :(得分:0)
这是在所有级别进行复制的解决方案:
#for windows use dill teh same way
import pickle
copy = lambda obj: pickle.loads(pickle.dumps(obj))
问题是:
class A: a = 1
x = A()
y = x
x.a = 5
print(y.a) #return's 5
带副本:
class A:a = 1
x = A()
y = copy(x)
x.a = 5
print(y.a) #return 1
您可以复制所需的任何内容,而不仅仅是类实例或类
答案 9 :(得分:-1)
如果你想创建另一个类的实例,那么只需创建它:
>>> class A(object):
... ARG=1
...
>>> a = A()
>>> A().ARG
1
>>> b = A()
>>> b.ARG
1
>>> a.ARG=2
>>> b.ARG
1