Qt模型项目之间是否存在重复数据?

时间:2014-12-23 03:33:15

标签: python qt memory pyqt pyside

有一种标准方式可以表示在QAbstractItemModels中使用的数据,其中有一个单独的数据项类,用于存储有关项目的数据及其在模型中的位置。

simpletreemodel示例(在Python中)说明了一种非常标准的方法,其中数据存储在TreeItem中,该class TreeItem(object): def __init__(self, data, parent=None): self.parentItem = parent self.itemData = data self.childItems = [] 初始化为:

TreeItem

请注意,每个TreeItems实例都包含其相关的特定于项目的数据(self.itemData),但还有一个子项列表(自身为TreeItem)及其父项item(也是A | |--B | |--C | | | |--D | |-E )作为属性。

为什么这不是一个非常低效的内存使用?让我们关注以下树形图中的项目B:

A.childItems[0]

天真地,一旦构造完整数据树,B的数据似乎将被存储四次。它将由C.parentItemD.parentItemB.itemData以及QAbstract*Model返回。

是否有一些Python魔法让这个成为低效的内存使用?

注意:即使在TreeItem被子类化时这些类型的数据容器被大量使用,这些容器本身实际上不包含Qt({{1}}的代码中没有Qt类被子类化)。所以这真的是一个基本的 Python 问题,而不是 Qt 问题。

可能相关的帖子

How do I determine the size of an object in Python?

2 个答案:

答案 0 :(得分:3)

在Python中,变量名称是对象的引用,因此所有这些不同的表达式实际上都引用相同的对象,即内存中的相同数据。尽管存在重复的引用,但没有重复的对象。因此,在您的示例中,A.childItems[0]C.parentItemD.parentItem都是引用到同一个对象B。因此,A.childItems[0].itemDataC.parentItem.itemDataD.parentItem.itemData都引用相同的B.itemData对象。

与神经网络评论中提到的LEGB文章相关的附注:如果A,B,C或D中的任何一个修改itemData引用的对象(通过调用方法或设置属性或数据)该对象的成员),然后所有其他人将看到更改。但是,如果将A.childItems[0]C.parentItemD.parentItem中的任何一个重新分配给其他对象,则只会影响父级:A.childItems[0] = something仅影响A.childItems中的第一个元素{1}}; C.parentItemD.parentItem以及B的任何其他引用仍然引用B

您可能会发现Python variable reference assignment上的答案很有用,但我发现它们并不清楚。我更喜欢Is Python pass-by-reference or pass-by-value,看看你的想法。

答案 1 :(得分:1)

正如@schollii和@hank指出的那样,PyQt和PySide是基于C ++的Qt的Python包装器。因此,如果Qt使用对象/指针(如您所描述的树中的父对象和子对象),则Python的对应变量也存储引用或指针对象。因此,内存中没有这些对象的重复,只是重复引用或指向内存中相同内容的指针。

这些链接是关于这个主题的精彩读物:

https://www.commandprompt.com/community/pyqt/c2341

http://www.swig.org/Doc1.3/Python.html#Python_nn18