如何复制课程?
- 2025-03-05 09:17:00
- admin 原创
- 105
问题描述:
deepcopy
fromcopy
不复制类:
>>> class A(object):
>>> ARG = 1
>>> B = deepcopy(A)
>>> A().ARG
>>> 1
>>> B().ARG
>>> 1
>>> A.ARG = 2
>>> B().ARG
>>> 2
这是唯一的办法吗?
B(A):
pass
解决方案 1:
总的来说,继承是正确的做法,正如其他海报所指出的那样。
但是,如果您确实想使用不同的名称重新创建相同的类型并且不包含继承,那么您可以这样做:
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]' (!)
解决方案 2:
正如您所猜测的,“复制”类的正确方法是继承:
class B(A):
pass
解决方案 3:
您可以使用工厂功能:
def get_A():
class A(object):
ARG = 1
return A
A = get_A()
B = get_A()
解决方案 4:
正如 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]
解决方案 5:
我认为您误解了此处静态变量的含义。在方法之外声明变量且不是 形式的任何地方self.some_thing
,该变量都将被视为类的静态变量(例如此处的 ARG 变量)。因此,更改静态变量的类的每个对象(实例)都会导致同一类中所有其他对象的更改。deepcopy 确实在这里完成了工作。
解决方案 6:
要复制具有属性的类__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_)
解决方案 7:
一种简单的方法是将类放入模块中,每次需要新副本时重新加载它。我认为这可以处理可变项,因为重新加载会重新创建所有内容。
解决方案 8:
这是各级复制的解决方案:
#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:
如果您只想创建类的另一个实例,那么只需这样做:
>>> class A(object):
... ARG=1
...
>>> a = A()
>>> A().ARG
1
>>> b = A()
>>> b.ARG
1
>>> a.ARG=2
>>> b.ARG
1
相关推荐
热门文章
项目管理软件有哪些?
热门标签
曾咪二维码
扫码咨询,免费领取项目管理大礼包!
云禅道AD