ctypes.Structure 在运行时修改 _fields_

发布于 2024-09-13 21:57:58 字数 783 浏览 7 评论 0原文

导入后是否可以修改 ctypes.Structure_fields_ 定义?

类似的东西:

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'

EDITS

我的用例是我有两个版本的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)]

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 additional 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)]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

冬天的雪花 2024-09-20 21:57:59

不,正如您在 中看到的源PyCStructType_Type是一个自定义元类(参见我刚刚指出的C代码中的第327ff行),Structure(第4136ff行)使用它(如公开的那样)在 5532ff 中)。 class 语句(特别是当自定义元类中的 __new__ 被调用以创建继承自 Structure 的新类时)是当所有 C-可访问字段实际上已定义(并且 ctypes 很好地使其他“走私”字段也无法从 Python 访问,以避免意外;-)。

确切地说,您想要解决什么问题,而在了解额外字段时您无法通过从头开始重建 A_STRUCT 来解决?例如,如果您的问题是已经存在“旧”A_STRUCT 的实例,那么,显然,这些实例没有您刚刚了解的新字段,因此修改类,即使通过一些令人难以置信的扭曲是可行的,也不会那么有用;-)。

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;-).

∞觅青森が 2024-09-20 21:57:59

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

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成员,父级的没有被替换,它仍然占用相同的内存(尽管无法使用像child.two这样的语句访问,并且第二个成员放置在它之后。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文