ctypes.Structure在运行时修改_fields_

时间:2010-08-10 17:44:31

标签: python struct runtime field ctypes

是否可以在导入后修改_fields_的{​​{1}}定义?

类似的东西:

ctypes.Structure

毫不奇怪,这失败了:

from ctypes import *

class A_STRUCT(Structure):
     _fields_ = [("one",c_int)]

A_STRUCT._fields_.append(("two",c_int))

x = A_STRUCT()
print x.one
print x.two

EDITS

我的用例是我有两个版本的0 Traceback (most recent call last): File "structEnumTest.py", line 10, in <module> print x.two AttributeError: 'A_STRUCT' object has no attribute 'two' 。版本2与附加到版本1末尾的附加字段相同。我希望避免这样的事情。我不知道在运行时需要哪个版本的结构。

A_STRUCT

2 个答案:

答案 0 :(得分:5)

不,正如您在the sources中看到的那样,PyCStructType_Type是一个自定义元类(请参阅我刚刚指出的C代码中的第327ff行)和Structure(第4136ff行)使用它(如5532ff中所述)。 class语句(特别是当调用自定义元类的__new__来创建继承自Structure的新类时)是所有C可访问字段实际定义的时候(并且它很好) ctypes要使其他“走私进入”的字段无法通过Python访问,以避免发生意外; - )。

您准确解决了什么问题,在您了解额外字段时,从头开始重建A_STRUCT无法解决这个问题?例如,如果您的问题是已经存在“旧”A_STRUCT的实例,那么很明显,这些实例没有您刚学到的新字段,因此修改了类,甚至如果通过一些令人难以置信的扭曲它是可行的,那将不是那么有用; - )。

答案 1 :(得分:2)

我知道这是一个非常古老的问题,但您可以通过子类化轻松解决您的问题:

class A_STRUCT_V1(Structure):
     _fields_ = [("one",c_int)]

class A_STRUCT_V2(A_STRUCT_V1):
     _fields_ = [("two",c_int)]
对于类型为A_STRUCT_V2

的对象,

'two'将紧跟在内存中的'one'之后

如果子类 fields 名称重复其父类 fields 成员,父级的不会被替换,它仍然需要相同的内存(尽管使用像child.two这样的语句是不可访问的,第二个成员放在它之后。