>>> from ctypes import *
>>> class A(Structure):
... _fields_ = [('a', c_int)]
... def __del__(self):
... print("destructor called")
...
>>> a = (A * 10)()
>>> a[0]
<__main__.A object at 0x7f93038cdd08>
>>> a[0]
destructor called
<__main__.A object at 0x7f93038cde18>
>>> a[0]
destructor called
<__main__.A object at 0x7f93038cdd08>
>>> a[0]
destructor called
<__main__.A object at 0x7f93038cde18>
为什么要在这里调用析构函数?为什么每次对象的地址都不一样?为什么 python 不会因双重释放错误而崩溃?
最佳答案
a
是一个代理对象,代表 Python 世界中的 C 结构数组。每次您对该对象进行索引时,ctypes
都会为您创建一个 A
类的新实例,以代理包含的 C 结构。
现在,因为您没有存储对这个新对象的任何引用,所以一旦它的 repr()
值在解释器中被回显,它也会被垃圾收集。
您可以将 a[0]
生成的对象存储在一个新变量中:
>>> foo = a[0]
>>> foo
<__main__.A object at 0x11061ea60>
这个对象将始终与您通过索引 a
的位置 0 创建的任何其他对象不同,但它们都表示相同的 C 结构,因为它们引用相同的地址:
>>> bar = a[0]
>>> foo is bar
False
>>> addressof(foo) == addressof(bar)
True
如果删除此引用,对象将再次被破坏(前提是您当然没有创建对 Python 代理对象的更多引用):
>>> del foo
destructor called
关于python - 为什么在对象未被销毁时调用 python ctypes 类描述符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37051280/