我有一个高度复杂的类:
class C:
pass
我有这个测试代码:
for j in range(10):
c = C()
print c
这使 :
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
<__main__.C instance at 0x7f7336a6cb00>
<__main__.C instance at 0x7f7336a6cab8>
可以很容易地看到 Python 开启了两个不同的值。在某些情况下,这可能是灾难性的(例如,如果我们将对象存储在其他一些复杂对象中)。
现在,如果我将对象存储在 List 中:
lst = []
for j in range(10):
c = C()
lst.append(c)
print c
我明白了:
<__main__.C instance at 0x7fd8f8f7eb00>
<__main__.C instance at 0x7fd8f8f7eab8>
<__main__.C instance at 0x7fd8f8f7eb48>
<__main__.C instance at 0x7fd8f8f7eb90>
<__main__.C instance at 0x7fd8f8f7ebd8>
<__main__.C instance at 0x7fd8f8f7ec20>
<__main__.C instance at 0x7fd8f8f7ec68>
<__main__.C instance at 0x7fd8f8f7ecb0>
<__main__.C instance at 0x7fd8f8f7ecf8>
<__main__.C instance at 0x7fd8f8f7ed40>
这解决了这个问题。
所以现在,我要问一个问题......有没有人可以用复杂的词(我的意思是,深刻的)解释 Python 如何处理对象引用?我想,这是一个优化问题(节省内存,或防止泄漏,......)
非常感谢。
编辑: 好的,让我们更具体一点。我很清楚python有时必须收集垃圾......但是,就我而言:
我有一个由 Cython 定义的类返回的列表:管理“节点”列表的“网络”类(网络和节点类都在 a 中定义Cython extension
)。每个节点都有一个对象 [然后转换为 (void *)] 'userdata' 对象。Nodes 列表是从 cython 内部填充的,而 UserData 是从 Python 脚本内部填充的。所以在python中,我有以下内容:
...
def some_python_class_method(self):
nodes = self.netBinding.GetNetwork().get_nodes()
...
for item in it:
a_site = PyLabSiteEvent()
#l_site.append(a_site) # WARN : Required to get an instance on 'a_site'
# that persits - workaround...
item.SetUserData(a_site)
稍后在相同的 python 类中使用相同的 cython getter 重用此节点列表:
def some_other_python_class_method(self, node):
s_data = node.GetUserData()
...
因此,似乎在节点列表的 UserDatas 中进行存储时,我的 python 脚本完全是盲目的,并且正在释放/重用内存。它通过使用附加列表(这里:'l_site')第二次引用(但显然是python方面的第一次)来工作。这就是为什么我必须更多地了解 Python 本身的原因,但似乎我实现 Python 之间通信的方式并Cython
负责解决必须面对的问题。