【问题标题】:Why doesn't deepcopy of classes preserve attributes? [duplicate]为什么类的深拷贝不保留属性? [复制]
【发布时间】:2014-05-07 16:47:35
【问题描述】:

在下面的示例中,我正在对基类进行深度复制并弄乱副本的属性。为什么这会破坏原始类的属性?有没有办法避免这种情况?我正在使用的当前代码结构不支持多重继承,所以我真的希望能够以某种方式复制该类。

>>> class Base(object):
...    foo = "bar"
... 
>>> base_copy = copy.deepcopy(Base)
>>> del base_copy.foo
>>> 
>>> base_again = copy.deepcopy(Base)
>>> hasattr(base_again, 'foo')
False
>>> 

【问题讨论】:

    标签: python copy deep-copy


    【解决方案1】:

    copy() 和 deepcopy() 旨在复制对象而不是类。当您传递一个类时,将返回原始类。

    Python documentation 说:

    此模块不会复制模块、方法、堆栈跟踪、堆栈帧、文件、套接字、窗口、数组等类型或任何类似类型。它通过返回原始对象不变来“复制”函数和类(浅层和深层);这与 pickle 模块处理这些的方式兼容。

    确实,在使用您的代码进行测试时,我们有:

    In [8]: base_copy is Base
    Out[8]: True
    

    您可以尝试按照其他答案中的建议与type() 搞混,但这很hackish。

    你可以的

    class B(A):
        pass
    

    这是我能想到的最接近复制的方法。

    【讨论】:

    • 我喜欢你的回答胜过我自己的回答。您可以使用type('B', (A,), {}) 在一行中从 A 继承。它不再是 hackish :)
    【解决方案2】:

    如copy documentation中所述:

    此模块不会复制模块、方法、堆栈跟踪等类型, 堆栈帧、文件、套接字、窗口、数组或任何类似类型。它 通过返回“复制”函数和类(浅层和深层) 原对象不变

    您可以尝试使用metaclasses:

    class Base(object):
        foo = "bar"
    
    # Create a new class called `base_copy` with attributes and base classes 
    # from Base without inheriting from Base
    base_copy = type('base_copy', Base.__bases__, dict(Base.__dict__))
    # Will delete attribute on `base_copy` class
    del base_copy.foo
    
    base_again = type('base_again', Base.__bases__, dict(Base.__dict__))
    
    print(hasattr(base_again, 'foo')) # True
    

    您可以尝试在dict(Base.__dict__) 对象上使用deepcopy 来复制list、dict 等对象。

    【讨论】:

    • 或多或少我在寻找什么。
    【解决方案3】:

    在构造函数中定义所有变量。 您可以创建一个新的构造函数,它根据提供的参数决定类对象中应该存在哪些字段。

    Class Foo:
         def __init__(self):
            self.param0 = 0
            self.param1 = 0
         def __init__(self,i):
            if i == 0:
                self.param0 = 0
            if i == 1: 
                self.param1 = 1
    

    【讨论】:

      猜你喜欢
      • 2023-04-05
      • 2014-01-10
      • 2012-03-23
      • 1970-01-01
      • 2010-09-16
      • 1970-01-01
      • 2011-03-22
      • 2011-02-09
      • 1970-01-01
      相关资源
      最近更新 更多