gpt4 book ai didi

python - 为什么在复制自定义对象时 deepcopy 失败并显示 "KeyError: ' __deepcopy_ _'"?

转载 作者:太空狗 更新时间:2023-10-29 20:55:54 26 4
gpt4 key购买 nike

我有一个像这样将字典转换为对象的类

class Dict2obj(dict):
__getattr__= dict.__getitem__

def __init__(self, d):
self.update(**dict((k, self.parse(v))
for k, v in d.iteritems()))

@classmethod
def parse(cls, v):
if isinstance(v, dict):
return cls(v)
elif isinstance(v, list):
return [cls.parse(i) for i in v]
else:
return v

当我尝试对对象进行深度复制时出现此错误

import copy
my_object = Dict2obj(json_data)
copy_object = copy.deepcopy(my_object)

File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy.py", line 172, in deepcopy
copier = getattr(x, "__deepcopy__", None)
KeyError: '__deepcopy__'

但是,如果我重写 Dict2obj 类中的 __getattr__ 函数,我就能够进行深度复制操作。请参见下面的示例

class Dict2obj(dict):

__getattr__= dict.__getitem__

def __init__(self, d):
self.update(**dict((k, self.parse(v))
for k, v in d.iteritems()))

def __getattr__(self, key):
if key in self:
return self[key]
raise AttributeError

@classmethod
def parse(cls, v):
if isinstance(v, dict):
return cls(v)
elif isinstance(v, list):
return [cls.parse(i) for i in v]
else:
return v

为什么我需要覆盖 __getattr__ 方法才能对此类返回的对象进行深层复制?

最佳答案

您的第一个类会出现此问题,因为 copy.deepcopy尝试调用 getattr(x, "__deepcopy__", None) .第三个参数的意义在于,如果对象的属性不存在,则返回第三个参数。

这在 the documentation for getattr() 中给出-

getattr(object, name[, default])

Return the value of the named attribute of object. name must be a string. If the string is the name of one of the object’s attributes, the result is the value of that attribute. For example, getattr(x, 'foobar') is equivalent to x.foobar. If the named attribute does not exist, default is returned if provided, otherwise AttributeError is raised.

如果基础 __getattr__提高 AttributeErrordefaultgetattr() 提供了参数函数调用 AttributeErrorgetattr() 捕获函数,它返回默认参数,否则它让 AttributeError冒泡。示例 -

>>> class C:
... def __getattr__(self,k):
... raise AttributeError('asd')
...
>>>
>>> c = C()
>>> getattr(c,'a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 3, in __getattr__
AttributeError: asd
>>> print(getattr(c,'a',None))
None

但在你的情况下,因为你直接分配 dict.__getitem____getattr__ ,如果在字典中找不到该名称,则会引发 KeyError ,不是 AttributeError因此它不会被 getattr() 处理和你的 copy.deepcopy()失败。

您应该处理 KeyError在你的getattr然后提高 AttributeError反而。示例 -

class Dict2obj(dict):

def __init__(self, d):
self.update(**dict((k, self.parse(v))
for k, v in d.iteritems()))

def __getattr__(self, name):
try:
return self[name]
except KeyError:
raise AttributeError(name)
...

关于python - 为什么在复制自定义对象时 deepcopy 失败并显示 "KeyError: ' __deepcopy_ _'"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33387801/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com