【问题标题】:How to copy all python instances to a new class?如何将所有 python 实例复制到一个新类?
【发布时间】:2013-07-19 11:13:09
【问题描述】:

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

预期用途是,假设我有“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 版本时(这样:)

VMPast=copy.deepcopy(VM1)
VM1.MyMethod(VMPast.MyButton[-1])

它会抛出以下错误:

AttributeError: AttributeSetter instance has no __call__ method

因为值:

VMPast.MyButton[-1]

被发送为:

'__deepcopy__'

而不是我想要的实际替换值...(按钮),所以如果 VMPast 已经是 VM 内实例的工作副本,那么这将在返回 deepcopy 的情况下起作用! 另一件事是,实例是动态的,我事先不知道原始类在那一刻将具有的名称或值。 非常感谢!

【问题讨论】:

  • 您的printmytext() 函数会创建一个 深层副本,并将其作为函数定义的默认值存储。它不会在每次调用时创建深层副本。
  • 深拷贝从不复制类定义,只复制实例属性。
  • 那么如何在不返回 __deepcopy__(memo) 而不是在更复杂的脚本中访问复制的值?我不能调用“VMPast.MyButton[-1]”,因为它会返回一个 __deepcopy__(memo),我在 VM 类中的方法还没有准备好使用...
  • 您需要分享您的原始代码和完整的回溯;我还不知道那里的代码发生了什么,但是您非常误解 deepcopy 的作用或 Python 实例和类之间的关系。
  • copy 模块寻找特殊的复制定制挂钩时,看起来好像原始类错误地实现了__deepcopy__ 属性。不知道我们在这里讨论的是什么代码,这是不可能确定的。

标签: python class copy instances


【解决方案1】:

深拷贝从不复制类定义,只复制实例属性。

它会创建一个新实例。 Python 实例仅持有对类定义的引用。只需在该实例上调用MyMethod on

VMPast.MyMethod()

只要类有这样的方法。

是您的特定阻止了成功的深拷贝:

class VariableManagerClass:
    def __getattr__(self, attr):
        return AttributeSetter(self, attr)

copy.deepcopy() 函数在实例上查找 .__deepcopy__() 方法,而您的 __getattr__ 挂钩则返回 AttributeSetter 类。

您可以先测试一下您的 attr 来防止这种情况发生:

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

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

【讨论】:

  • 真棒马丁,我很难过,我不明白为什么,但它有效,我真的很感激 :)
【解决方案2】:

如果您只关心类的值(属性),我认为您可以调用__dict__ 方法来获取这些值。

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'}

如果这是要问的,这里有一个相关的问题:List attributes of an object

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-18
    • 1970-01-01
    • 2014-08-10
    相关资源
    最近更新 更多