考虑一个简单的数据类:
from ctypes import c_int32, c_int16
from dataclasses import dataclass
@dataclass
class MyClass:
field1: c_int32
field2: c_int16
根据文档,如果我们想使这个数据类兼容ctypes
,我们必须像这样定义它:
import ctypes
from ctypes import Structure, c_int32, c_int16, sizeof
from dataclasses import dataclass, fields
@dataclass
class MyClass(ctypes.Structure):
_pack_ = 1
_fields_ = [("field1", c_int32),("field2", c_int16)]
print(ctypes.sizeof(MyClass))
但不幸的是,这个定义剥夺了我们数据类的便捷特性,即所谓的“dunder”方法。例如,constructor( __init__()
) 和 string representative( __repr__()
) 变得不可用:
inst = MyClass(c_int32(42), c_int16(43)) # will give error
问:在不丢失“dunder”方法的情况下,使数据类与 ctypes 兼容的最优雅和最惯用的方法是什么?
如果我们问我,这段代码乍一看似乎是可行的:
@dataclass
class MyClass(ctypes.Structure):
field1: c_int32
field2: c_int16
_pack_ = 1
MyClass._fields_ = [(field.name, field.type) for field in fields(MyClass)] #_pack_ is skipped
由于我是初学者,我不确定这段代码是否不会导致一些其他不明显的问题。