deepcopy从copy不会复制一个类:
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
Run Code Online (Sandbox Code Playgroud)
这是唯一的方式吗?
B(A):
pass
Run Code Online (Sandbox Code Playgroud)
Flo*_*ker 45
一般来说,继承是正确的方式,正如其他海报已经指出的那样.
但是,如果您真的想要使用不同的名称重新创建相同的类型而没有继承,那么您可以这样做:
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'
Run Code Online (Sandbox Code Playgroud)
您必须小心可变属性值:
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]' (!)
Run Code Online (Sandbox Code Playgroud)
Dav*_*son 20
正如你所推测的那样,"复制"一个类的正确方法是继承:
class B(A):
pass
Run Code Online (Sandbox Code Playgroud)
您可以使用工厂功能:
def get_A():
class A(object):
ARG = 1
return A
A = get_A()
B = get_A()
Run Code Online (Sandbox Code Playgroud)
正如Florian Brucker指出的那样,可变的类属性存在问题。您也不能只deepcopy(cls.__dict__)使用新样式的对象。为了解决这个问题,我做了以下工作。我敢肯定,有足够的决心可以打破这一点。但是,它将在更多情况下起作用。
from copy import deepcopy
from typing import TypeVar
Cls = TypeVar('Cls')
# This type hint is a dirty lie to make autocomplete and static
# analyzers give more useful results. Crazy the stuff you can do
# with python...
def copy_class(cls: Cls) -> Cls:
copy_cls = type(f'{cls.__name__}Copy', cls.__bases__, dict(cls.__dict__))
for name, attr in cls.__dict__.items():
try:
hash(attr)
except TypeError:
# Assume lack of __hash__ implies mutability. This is NOT
# a bullet proof assumption but good in many cases.
setattr(copy_cls, name, deepcopy(attr))
return copy_cls
def test_copy_class():
class A(object):
mutable_class_var = []
ACopy = copy_class(A)
a = A()
acopy = ACopy()
acopy.mutable_class_var.append(1)
assert a.mutable_class_var == []
assert A.mutable_class_var == []
assert ACopy.mutable_class_var == [1]
assert acopy.mutable_class_var == [1]
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
48299 次 |
| 最近记录: |