Is it possible to modify the _fields_
definition of the ctypes.Structure
after it's been imported?
Something like:
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
Not surprisingly this fails with:
0
Traceback (most recent call last):
File "structEnumTest.py", line 10, in <module>
print x.two
AttributeError: 'A_STRUCT' object has no attribute 'two'
EDITS
My use case is that I have two version of A_STRUCT
. Version 2 is the same with addit开发者_JS百科ional fields appended to the end of version one. I was hoping to avoid having something like this. I do not know which version of the struct is needed until run-time.
class A_STRUCT_V1(Structure):
_fields_ = [("one",c_int)]
class A_STRUCT_V2(Structure):
_fields_ = [("one",c_int),("two",c_int)]
No, as you can see in the sources, PyCStructType_Type
is a custom metaclass (see lines 327ff in the C code I just pointed to) and Structure
(lines 4136ff) uses it (as exposed in 5532ff). The class
statement (specifically when the __new__
from the custom metaclass gets called to make the new class which inherits from Structure
) is when all C-accessible fields are actually defined (and it's nice of ctypes
to make other "smuggled in" fields inaccessible from Python as well to avoid accidents;-).
What problem, exactly, are you trying to solve, that you couldn't solve by rebuilding A_STRUCT
from scratch at the time you learn about the extra fields? For example, if your issue is that there are instances of the "old" A_STRUCT
already around, well, obviously, those instances don't have the new fields you've just learned about, so modifying the class, even if through some incredible contortion it was feasible, wouldn't be all that useful;-).
I know this is a very old question, but you can solve your problem easily by subclassing:
class A_STRUCT_V1(Structure):
_fields_ = [("one",c_int)]
class A_STRUCT_V2(A_STRUCT_V1):
_fields_ = [("two",c_int)]
'two' will immediately follow 'one' in memory for objects of type A_STRUCT_V2
If the subclasses fields name duplicates its parent class fields member, the parent's is not replaced, it still takes the same memory (though is inaccessible with a statement like child.two, and the second member is placed after it.
精彩评论