代码之家  ›  专栏  ›  技术社区  ›  Mark

ctypes.structure在运行时修改字段

  •  2
  • Mark  · 技术社区  · 14 年前

    是否可以修改 _fields_ 定义 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
    

    不足为奇,这在以下情况下失败了:

    0
    Traceback (most recent call last):
      File "structEnumTest.py", line 10, in <module>
        print x.two
    AttributeError: 'A_STRUCT' object has no attribute 'two'
    

    编辑

    我的用例是我有两个版本的 A_STRUCT . 版本2与版本1末尾附加的其他字段相同。我希望避免这样的事情。在运行时之前,我不知道需要哪个版本的结构。

    class A_STRUCT_V1(Structure):
         _fields_ = [("one",c_int)]
    
    class A_STRUCT_V2(Structure):
         _fields_ = [("one",c_int),("two",c_int)]
    
    2 回复  |  直到 6 年前
        1
  •  5
  •   Alex Martelli    14 年前

    不,你可以在里面看到 the sources , PyCStructType_Type 是一个自定义元类(参见我刚才提到的C代码中的第327FF行),并且 Structure (第4136FF行)使用它(如5532FF中所示)。这个 class 声明(特别是当 __new__ 从自定义元类调用以生成继承自的新类 结构 )当所有C-可访问字段都被实际定义时(这是很好的 ctypes 使其他“走私”字段无法从python访问,并避免发生意外;-)。

    你到底想解决什么问题,你不能通过重建来解决 A_STRUCT 从零开始,在你学习额外的领域?例如,如果您的问题是存在“旧”的实例 A-结构 显然,这些实例已经没有您刚刚学到的新字段了,所以修改类,即使通过一些不可思议的扭曲它是可行的,也不是那么有用;-)。

        2
  •  2
  •   sheridp    8 年前

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

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

    对于类型为A结构_v2的对象,“two”将立即跟在内存中的“one”后面

    如果子类 领域 名称重复其父类 领域 成员,父级的 不被取代 ,它仍然占用相同的内存(尽管使用child.two之类的语句无法访问,但第二个成员放在它之后。