我尝试将一些诊断添加到嵌套的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.first
和t
不等同?如果我不能设置它,为什么s.first.helper
不会触发警告?
答案 0 :(得分:1)
在第二个示例中,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
实例,因此您可以设置和读取属性。
答案 1 :(得分:0)
如果使用复制模块,则可以获取您创建的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