如何调试调用Python';是否针对自定义类型设置s copy.deepcopy()?
在我的代码中,我试图使用如何调试调用Python';是否针对自定义类型设置s copy.deepcopy()?,python,deep-copy,Python,Deep Copy,在我的代码中,我试图使用copy.deepcopy复制一个类的实例。问题在于,在某些情况下,它会出现以下错误: TypeError: 'object.__new__(NotImplementedType) is not safe, use NotImplementedType.__new__()' 经过大量挖掘,我发现我能够使用以下代码重现错误: import copy copy.deepcopy(__builtins__) 问题似乎是,在某个时刻,它试图复制NotImplementedT
copy.deepcopy
复制一个类的实例。问题在于,在某些情况下,它会出现以下错误:
TypeError: 'object.__new__(NotImplementedType) is not safe, use NotImplementedType.__new__()'
经过大量挖掘,我发现我能够使用以下代码重现错误:
import copy
copy.deepcopy(__builtins__)
问题似乎是,在某个时刻,它试图复制NotImplementedType
builtin。问题是它为什么这样做?我没有在我的课堂上重写\uuuuuu deepcopy\uuuuu
,而且这种情况并非总是发生。有没有人有任何技巧来追踪制作这种类型副本的请求来自哪里
我已经在
copy
模块本身中添加了一些调试代码,以确保这是正在发生的事情,但是问题发生的点是递归堆栈,很难充分利用我看到的内容。您可以覆盖u deepcopy_u_u_u__方法:()
为了让类定义自己的复制实现,它可以定义特殊的方法\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。调用前者实现浅层复制操作;不传递其他参数。调用后者来实现深度复制操作;它传递了一个参数,即备忘录字典。如果\uuuu deepcopy\uuuuu()实现需要对组件进行深度复制,它应该调用deepcopy()函数,将组件作为第一个参数,将备忘录字典作为第二个参数
否则,您可以将模块保存在全局列表或其他内容中。最后,我在
副本
源代码中进行了一些挖掘,并提出了以下解决方案:
from copy import deepcopy, _deepcopy_dispatch
from types import ModuleType
class MyType(object):
def __init__(self):
self.module = __builtins__
def copy(self):
''' Patch the deepcopy dispatcher to pass modules back unchanged '''
_deepcopy_dispatch[ModuleType] = lambda x, m: x
result = deepcopy(self)
del _deepcopy_dispatch[ModuleType]
return result
MyType().copy()
我意识到这使用了一个私有API,但我找不到另一个干净的方法来实现同样的事情。我在网上做了一个测试,发现其他人使用了相同的API,没有任何麻烦。如果将来情况发生变化,我将承担责任
我也知道这不是线程安全的(如果一个线程需要旧的行为,而我在另一个线程上复制,我会被拧紧),但这对我来说不是一个问题
希望这能在某些方面帮助其他人。您可以使用复制模块支持的重写类的deepcopy行为,该类包含指向模块的指针,如上所述。特别是,您可以为该类定义
\uuu getstate\uu
和\uu setstate\uu
。例如:
>>> class MyClass:
... def __getstate__(self):
... state = self.__dict__.copy()
... del state['some_module']
... return state
... def __setstate__(self, state):
... self.__dict__.update(state)
... self.some_module = some_module
你的实例引用的是什么类型的东西?@Matt:这些实例包含configobj实例和其他东西(其他东西是标准列表和dict等)。好的,问题似乎是其中一个成员是包含模块引用的dict。所以现在的问题似乎是,当遇到某些类型时,如何让deepcopy停止,而不尝试复制它们(在我的例子中是模块和类)。有什么线索吗?我刚刚注意到你说有问题的模块是dict的一个成员。如果有一个(单个)对象拥有该dict,那么该对象可以定义定制的getstate/setstate来适当地损坏dict。如果dict被多个对象共享,那么您可能会使用monkey补丁方法卡住。(或者稍微重构一下代码。)