Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何将所有python实例复制到新类?_Python_Class_Copy_Instances - Fatal编程技术网

如何将所有python实例复制到新类?

如何将所有python实例复制到新类?,python,class,copy,instances,Python,Class,Copy,Instances,我想深度复制一个类的所有实例,但不复制给定类的定义和规则 预期用途是,假设我有“OriginalClass”类,它的实例就是我存储的变量。当程序继续运行时,我希望能够使用OriginalClass以前的“快照”,从中我将只使用值(我不会在那里存储新值,因此不需要继承任何规则) 上面的简单示例非常有效,与我想做的非常相似: import copy class VM: #nothing in the class pass VM1=VM() VM1.test=dict() VM1.

我想深度复制一个类的所有实例,但不复制给定类的定义和规则

预期用途是,假设我有“OriginalClass”类,它的实例就是我存储的变量。当程序继续运行时,我希望能够使用OriginalClass以前的“快照”,从中我将只使用值(我不会在那里存储新值,因此不需要继承任何规则)

上面的简单示例非常有效,与我想做的非常相似:

import copy

class VM:
    #nothing in the class
    pass

VM1=VM()
VM1.test=dict()
VM1.test['one']="hello"

def printmytext(VMPast=copy.deepcopy(VM1)):

    g.es(VMPast.test['one'])

VM1.test="Bye"

printmytext() #Returns "hello"
但这一想法将取代:

VMPast=copy.deepcopy(VM1)
对于工作代码,我不知道如何编写,它将复制实例和字典,但不会复制定义

原因是,在我的程序中使用deepcopy版本时(这样:)

它抛出以下错误:

AttributeError: AttributeSetter instance has no __call__ method
因为:

VMPast.MyButton[-1]
已发送为:

'__deepcopy__'
而不是我想要的实际替代值。。。(按钮),因此,如果vmpass已经是VM内实例的工作副本,那么在返回deepcopy之前,它就可以工作了! 另一件事是,实例是动态的,我事先不知道原始类在那个时刻将具有哪些名称或值。
多谢各位

深度副本从不复制类定义,只复制实例属性

而是创建一个新实例。Python实例仅包含对类定义的引用。只需在该实例上调用
MyMethod

VMPast.MyMethod()
如果类有这样一个方法

是您的特定类阻止了成功的深度复制:

class VariableManagerClass:
    def __getattr__(self, attr):
        return AttributeSetter(self, attr)
copy.deepcopy()
函数在实例上查找
\uuuu deepcopy()
方法,而您的
\uuuu getattr\uuuuu
钩子将返回一个
AttributeSetter

您可以通过先测试一下
attr
来防止这种情况:

class VariableManagerClass:
    def __getattr__(self, attr):
        if attr.startswith('_'):
            raise AttributeError(attr)
        return AttributeSetter(self, attr)

这表明您的类不处理私有属性或特殊方法名。

如果您只关心类的值(属性),我想您可以调用
\uuuuuuuu dict\uu
方法来获取这些值

In [1]: class Foo():
   ...:     pass
   ...: 

In [2]: foo = Foo()

In [3]: foo.bar1 = 'derp'

In [4]: foo.bar2 = 'derp derp'

In [5]: foo.__dict__
Out[5]: {'bar1': 'derp', 'bar2': 'derp derp'}

如果这就是问题所在,那么这里有一个相关的问题:

您的
printmytext()
函数创建一个深度副本,并将其存储为函数定义的默认值。它不会在每次调用时创建深度副本。深度副本从不复制类定义,只复制实例属性。那么,我如何访问复制的值,而不在更复杂的脚本中返回_udeepcopy_;(memo)?我不能调用“vmpass.MyButton[-1]”,因为它将返回一个_deepcopy__(memo),我在VM类中的方法还没有准备好使用它…您需要共享您的原始代码和完整的回溯;我还不知道你的代码是怎么回事,但是你非常误解了deepcopy的作用,或者Python实例和类之间的关系。当
copy
模块寻找一个特殊的复制定制挂钩时,看起来原始类不正确地具体化了
\uu deepcopy\uuu
属性。不知道我们在这里谈论的是什么代码,这是不可能确定的。太棒了,马丁,我很难过,我不太明白为什么,但它起作用了,我真的很感谢:)
In [1]: class Foo():
   ...:     pass
   ...: 

In [2]: foo = Foo()

In [3]: foo.bar1 = 'derp'

In [4]: foo.bar2 = 'derp derp'

In [5]: foo.__dict__
Out[5]: {'bar1': 'derp', 'bar2': 'derp derp'}