无法将属性添加到 ctypes 中的嵌套结构

Unable to add attribute to a nested structure in ctypes

我试图向嵌套的 ctypes 结构添加一些诊断,但没有成功,我想知道原因。按预期工作的简单示例:

import ctypes

class FirstStruct(ctypes.Structure):
    _fields_ = [('ch', ctypes.c_ubyte)]

f = FirstStruct()

print type(f)
print hasattr(f, 'helper')
f.helper = 'xyz'
print hasattr(f, 'helper')

这些行打印出了我的预期:

<class '__main__.FirstStruct'>
False
True

但是当我在另一个结构中使用它时它失败了:

class SecondStruct(ctypes.Structure):
    _fields_ = [('first', FirstStruct)]

s = SecondStruct()

print type(s.first)
print hasattr(s.first, 'helper')
s.first.helper = 'xyz'
print hasattr(s.first, 'helper')

以上结果

<class '__main__.FirstStruct'>
False
False

有人可以解释一下区别吗? (我在 Python 2.7.8 上 运行 它。请注意,我不想更改结构本身,但想在 ctypes 结构之外添加一个额外的变量。)


编辑:

这里有一个更直接的例子:

import ctypes

class FirstStruct(ctypes.Structure):
    _fields_ = [('ch', ctypes.c_ubyte)]

class SecondStruct(ctypes.Structure):
    _fields_ = [('first', FirstStruct)]

f = FirstStruct()
s = SecondStruct()

f.helper = 'aaa'
s.first.helper = 'bbb'
s.first.ch = 0
t = s.first
t.helper = 'ccc'
t.ch = 12

print f.helper          # aaa
print t.ch              # 12
print s.first.ch        # 12
print t.helper          # ccc
print s.first.helper    # AttributeError: 'FirstStruct' object has no attribute 'helper'

问题是:为什么 s.firstt 不等价,为什么 s.first.helper 不触发警告,如果我毕竟无法设置它?

如果您使用复制模块,您可以获得您创建的ctype 对象的当前快照。所以尝试:

import copy
import ctypes

class FirstStruct(ctypes.Structure):
    _fields_ = [('ch', ctypes.c_ubyte)]

f = FirstStruct()

print type(f)
print hasattr(f, 'helper')
f.helper = 'xyz'
print hasattr(f, 'helper')

t = copy.copy(f)
print hasattr(t, 'helper')
>>> True

在您的第二个示例中,s.first 返回内部结构的副本。您可以通过查看其 id():

来了解这一点
>>> id(s.first)
112955080L
>>> id(s.first)  # didn't change
112955080L
>>> f=s.first    # capture a reference the object returned
>>> id(f)        # still the same
112955080L
>>> id(s.first)  # changed!
113484232L

发生的事情是返回的新副本一直被分配到相同的地址,但立即被释放。引用后,副本在另一个地址。

所以你正在创建一个helper属性,只是在一个临时对象上。

在您的第一个示例中,f 直接引用 FirstStruct 实例,因此您可以设置和读取属性。