gpt4 book ai didi

python - 为什么在对象未被销毁时调用 python ctypes 类描述符?

转载 作者:行者123 更新时间:2023-11-28 16:25:37 27 4
gpt4 key购买 nike

>>> 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com