这个问题与another question有关我昨天发布了,尽管它本质上更笼统。
由于我提到的线程,我一直在尝试确定哪些对象可以被复制、腌制、编码,哪些对象不能。
在这样做的时候,我偶然发现了这个谜题:
new_obj = copy.deepcopy(my_obj)
function_that_uses_my_new_obj(new_obj)
抛出:
function_that_uses_my_new_obj(new_obj)
RuntimeError: Internal C++ object (Pyside.QtGui.QWidget) already deleted
现在,由于 my_obj
是 C++
对象,我可以理解该错误。那个特定问题的原因是另一个线程的主题。
但是,当我尝试时:
function_that_uses_my_new_obj(copy.deepcopy(my_obj))
我什么也没得到。程序正常运行到这一行,停在那里几秒钟并停止执行,该行之后的代码不运行,不抛出异常/错误/警告,Python 提示符准备好接受任何新命令。
编辑
出于某种原因,使用 copy()
方法而不是像这样的 deepcopy()
:
function_that_uses_my_new_obj(copy.copy(my_obj))
导致抛出相同的异常。因此,必须有某个点 deepcopy
决定停止或正在停止并触发执行结束。我不明白的是为什么没有提出任何通知用户...
最佳答案
Copy 和 pickle 会在所有情况下尝试完成它们的工作,但对于 python 中的许多事情,结果的责任只落在程序员身上。
按照难度递增的顺序:
真正可以安全复制或 pickle 的对象基本上是原始类型、字符串、列表、字典、数字等。
还有很多对象明确支持魔法方法(比如
__copy__
和__deepcopy__
)然后是复制将尽力而为并成功的对象。对于简单对象,仅包含对先前级别中对象的引用。
最后是真正不安全的复制:
- 具有许多循环引用的大型对象图
- 正在被其他线程使用和修改的对象。
- 具有外部资源的对象:文件、连接等。
- 包装或代理 C 库的对象
关于Python copy.deepcopy() 在没有引发警告、异常或错误的情况下失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22707756/