Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.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
Python 使用Qt和Pickle的断言错误疯狂_Python_Pyqt_Pickle - Fatal编程技术网

Python 使用Qt和Pickle的断言错误疯狂

Python 使用Qt和Pickle的断言错误疯狂,python,pyqt,pickle,Python,Pyqt,Pickle,每次拖放(从一个QListWidget到另一个)时,其强度和复杂性断言错误都让我发疯。我知道,AssertionError是由类实例的一个属性引起的(类实例变量通过.setData()附加到QListWidget项)。其中一个属性与pickle不兼容。如果您能告诉我如何处理此问题以及如何有效地调试它,我将不胜感激。到目前为止,唯一的解决方案是逐个检查每个类属性,将其设置为“无”,然后检查这是否解决了断言错误问题。但是这种方法极其乏味和耗时 稍后编辑: 经过数小时的调试,我将代码压缩到了最低限度。

每次拖放(从一个QListWidget到另一个)时,其强度和复杂性断言错误都让我发疯。我知道,
AssertionError
是由类实例的一个属性引起的(类实例变量通过.setData()附加到QListWidget项)。其中一个属性与
pickle
不兼容。如果您能告诉我如何处理此问题以及如何有效地调试它,我将不胜感激。到目前为止,唯一的解决方案是逐个检查每个类属性,将其设置为“无”,然后检查这是否解决了
断言错误
问题。但是这种方法极其乏味和耗时

稍后编辑: 经过数小时的调试,我将代码压缩到了最低限度。这与我在Qt小部件(如QListWidget)无法使用
pickle
执行任务时遇到的问题完全相同

简短信息:

声明ClassA和ClassB的两个实例。然后instB存储在instA属性中。反之亦然:instA存储在instB属性中。其余的很简单:instA via.setData()被分配给ListWidget项。拖动该项会导致pickle失败。 请告知今后如何避免这种情况,原因是什么,以及是否有可能的解决方案



问题似乎在于循环引用-
instA
references
instB
,反之亦然。 以下是我的作品:

class Base(dict):
    def __init__(self):
        super(Base, self).__init__()

    def setInstB(self, instB):
        self['instB']=instB

class ClassA(Base):
    def __init__(self):
        super(ClassA, self).__init__()

class ClassB(Base):
    def __init__(self):
        super(ClassB, self).__init__()

    def setInstA(self, instA):
        self.instA=instA

if __name__ == '__main__':

    import pickle

    instA=ClassA()
    instB=ClassB()

    instA.setInstB(instB)
    # omit the cyclic reference
    #instB.setInstA(instA)

    pickle.dumps(instA)
instB.setInstA(instA)
中进行注释会复制错误消息。
因此,如果您可以在没有循环引用的情况下生存,这可能是最简单的解决方法。

QtCore.pyqtSetPickleProtocol()
QtCore.pyqtPickleProtocol()
见:

所以


可能会有办法。

这里的新手……但是你有元组中的dict吗?你检查过你的问题是否与这个问题重复吗?我读过你提到的问题。据说
有一些数据是旧的pickle协议无法处理的。要解决你的问题,请使用pickle.HIGHEST\u协议
。我不清楚如何使用PyQt设置“use pickle.HIGHEST_PROTOCOL”覆盖。有人知道吗?问题在于QListWidget的拖放功能背后,该功能依赖于
pickle
模块写入/读取数据。而前面提到的
.HIGHEST_PROTOCOL
解决方案可能在代码处理的情况下工作直接使用pickle
PyQt时,不清楚如何实现它因为所有的酸洗都是通过Qt/QListWidget进行的。
pickle
并没有具体说明到底是什么导致了它的混淆。很难跟踪这个问题。我想知道是否存在一个可以避免往返或掉头的解决方案。您能提供一些通过
setData
附加的类的详细信息吗?是您编写的类还是Q类t类?如果是您的类,请发布代码:)如果它不会抛出
AttributeError:module对象没有属性pyqtSetPickleProtocol
,这可能是我的解决方案。可能是PyQt缺少
.pyqtSetPickleProtocol()
方法吗?它在我的控制台上工作。您使用的是什么版本的PyQt?根据这些发行说明,该函数是在4.10.1中引入的。不幸的是,我不能放弃代码中的循环引用。我非常依赖他们。您认为可以使用
.pyqtSetPickleProtocol()
方法来代替吗?
QtCore.pyqtSetPickleProtocol()
QtCore.pyqtPickleProtocol()
QtCore.pyqtSetPickleProtocol(pickle.HIGHEST_PROTOCOL)