【发布时间】:2023-03-16 13:09:01
【问题描述】:
在enum 模块存在之前,c_int 或相关类型经常被用作替代枚举。但这没有也没有检查类型。
既然python有一个enum模块,有没有办法直接使用ctypes?
【问题讨论】:
在enum 模块存在之前,c_int 或相关类型经常被用作替代枚举。但这没有也没有检查类型。
既然python有一个enum模块,有没有办法直接使用ctypes?
【问题讨论】:
是的,由于 ctypes 允许我们选择使用自定义类,我们可以轻松创建自己的 CEnum 类。枚举类型由 ctypes 自动检查。
from ctypes import windll
from enum import IntEnum
class CEnum(IntEnum):
@classmethod
def from_param(cls, self):
if not isinstance(self, cls):
raise TypeError
return self
class EnumA(CEnum):
CONST = 0
class EnumB(CEnum):
CONST = 0
这是一个示例(滥用类型,但正确显示了用法):
windll.kernel32.GetModuleHandleA.argtypes = [EnumA]
>>> windll.kernel32.GetModuleHandleA(EnumA.CONST)
>>> windll.kernel32.GetModuleHandleA(EnumB.CONST)
ArgumentError: argument 1: <class 'TypeError'>:
顺便说一句,我已经切换到 cffi,它原生支持枚举,并使用 c 定义,与 ctype 对应物相比,它恰好更简洁。
【讨论】:
ValueError - 显示的错误消息也看起来很奇怪,难道不是 ValueError: 0 is not a valid EnumA?
ctypes.Structure 定义中使用 CEnum 子类作为 C 类型。我为此创建了一个新的question。