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

时间:2017-09-25 10:22:58

标签: python 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不会触发警告?

2 个答案:

答案 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