Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/285.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
在python3中创建自定义类对象的deepcopy?_Python_Python 3.x_Class_Deep Copy - Fatal编程技术网

在python3中创建自定义类对象的deepcopy?

在python3中创建自定义类对象的deepcopy?,python,python-3.x,class,deep-copy,Python,Python 3.x,Class,Deep Copy,我试图实现类似于如果x是一个列表,那么y=list(x)应该是x的深度副本 到目前为止,我有以下类代码: from copy import deepcopy class CustomClass: def __init__(self, foo): if isinstance(foo, CustomClass): self = deepcopy(foo) else: self._foo = foo 现在如果我跑

我试图实现类似于如果
x
是一个列表,那么
y=list(x)
应该是
x
的深度副本

到目前为止,我有以下类代码:

from copy import deepcopy
class CustomClass:
    def __init__(self, foo):
        if isinstance(foo, CustomClass):
            self = deepcopy(foo)
        else:
            self._foo = foo
现在如果我跑

A = CustomClass(bar)
B = CustomClass(A)
print(B._foo)

我收到一个错误
AttributeError:“CustomClass”对象没有属性“\u foo”
。我不确定这里到底出了什么问题。例如,如果我在If语句中添加一行
print(self.\u foo)
,我将看到deepcopy已成功分配给self。是否有办法实现此deepcopy功能?

如评论中所述,分配给
self
没有帮助。问题是当调用
\uuuu init\uuuu(…)
时,类已经被创建,并且引用被保留在类之外(即由Python解释器/运行时)。而且,由于
\uuuu init\uuuuu(…)
不返回任何东西(特别是它自己的引用),因此无法从那里更改外部引用,而您尝试
深度复制时会这样做

在Python中,当调用例如
CustomClass(foo)
时,对象创建实际上是一个两步过程。首先,在调用
\uuuu init\uuuuuuu(…)
之前,运行库调用类上的另一个静态方法,即
\uuuuuuunew\uuuuu(…)
。这是构造实际对象的地方,而该类方法实际上返回对该对象的引用。因此,从理论上讲,在
\uuuu new\uuu(…)
方法中进行
deepcopy
应该是可能的(如果您知道如何进行)。但是,在调用
\uuuunew\uuuuu(…)
返回后,运行时将继续创建过程并调用
\uuuuuuinit\uuu(…)
方法。因此,在这种情况下,您还需要确保此调用不会更改新复制的对象中的任何内容

不过,一种更简单的方法是允许系统为您创建一个新对象(通过自动调用
\uuuuu new\uuuu(…)
),然后将新图像“形成”为原始对象的(深度复制)图像。这可以通过深度复制原始对象的所有属性并将它们放入新对象中来实现。如果所有属性都已知,可以通过显式列出它们并为它们分配(deepcopied)计算来实现:

class CustomClass:
    def __init__(self, foo):
        if isinstance(foo, CustomClass):
            # if foo is CustomClass, deepcopy all its attributes
            self._foo = deepcopy(foo._foo)
            # return to not perform "normal" initialization
            return
        # This will only execute if foo is _not_ a CustomClass object
        self._foo = foo 
但是,这种方法有点脆弱,因为它要求在复制过程中不会忘记任何属性,并且如果有人正在执行类似操作,则不会动态添加新属性(或者不会复制新属性)

cc = CustomClass(4)
cc.dynamic = 5
cc.dynmaic
将不被复制(而
deepcopy
将被复制)。因此,更好的方法是使用内部字典,在创建所有属性时保留对它们的引用:

class CustomClass:
    def __init__(self, foo):
        if isinstance(foo, CustomClass):
            # if foo is CustomClass, deepcopy all its attributes
            self.__dict__ = {key: deepcopy(value) for key, value in foo.__dict__.items()}
            # return to not perform "normal" initialization
            return
        # This will only execute if foo is _not_ a CustomClass object
        self._foo = foo 

这里使用对象的内部
\uuu dict\uu
。它引用所有属性,包括任何动态添加的属性,然后我
deepcopy
将每个属性分配给我们新创建的对象,模仿“普通”的
deepcopy
调用的行为。

因为
B
满足if语句
if-isinstance(foo,CustomClass)
so
self.\u foo
从来都不是created@coderoftheday对不起,我不完全明白。我想我有点不明白为什么
self=deepcopy(a)
不复制属性
a.\u foo
B
。但是
a
CustomClass
的一个实例,那么为什么要创建
self.\u foo
指定给
self
在函数之外绝对没有效果(在这种情况下,在函数内部绝对没有影响,因为它随后不会使用
self
)。感谢您的详细解释,非常感谢!)