编程语言
首页 > 编程语言> > Python copy.deepcopy()失败而不会引发警告,异常或错误

Python copy.deepcopy()失败而不会引发警告,异常或错误

作者:互联网

这个问题与我昨天发布的another question有关,虽然它本质上更为通用.

由于我提到的线程,我一直在尝试确定哪些对象可以被复制,pickle,marshaled以及哪些对象不能.

在这样做时,我偶然发现了这个难题:

new_obj = copy.deepcopy(my_obj)
function_that_uses_my_new_obj(new_obj)

抛出:

06001

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决定停止或正在停止并触发执行的结束.我没有得到的是为什么没有提出通知用户…

解决方法:

你的断言“my_obj是一个C对象”看起来非常明显错误:my_obj实际上是一个围绕C对象的python包装器.所以代码如:

    widget = QtGui.QWidget()
    my_obj = copy.deepcopy(widget)

将只创建python包装器的副本,保持底层C对象不变.这解释了为什么尝试调用其中一个复制的包装方法会产生RuntimeError.包装器的副本从来没有相应的底层C对象,因此它的行为就像它已被删除一样.

在“普通”PySide / PyQt代码中,这种事情很容易发生.有时,如果你不小心保持对python端对象的引用,Qt可以删除C部分,留下一个“空”包装器.在这种情况下,您将看到完全相同的RuntimeError.

标签:python,debugging,pyside,deep-copy,copy
来源: https://codeday.me/bug/20190830/1771755.html