gpt4 book ai didi

python - 元类与 ctypes 结构冲突

转载 作者:行者123 更新时间:2023-11-28 23:04:48 24 4
gpt4 key购买 nike

我正在尝试为我在此处创建的类创建一个元类:ctypes variable length structures

我想简化 Points 类,使其看起来像这样(Python 3.2):

class Points(c.Structure, metaclass=VariableMeta):
_fields_ = [
('num_points', c.c_uint32),
('points', 'Point*self.num_points')
]
def __init__(self):
self.num_points = 0
self.points = [0,]*MAX_SIZE

这是我目前拥有的元类:

class VariableMeta(type):
def __new__(cls, name, bases, dct):
dct['_inner_fields'] = dct['_fields_']
dct['_fields_'] = [('_buffer', c.c_byte*MAX_PACKET_SIZE)]
return type.__new__(cls, name, bases, dct)

def parse(self):
fields = []
for name, ctype in self._inner_fields:
if type(ctype) == str:
ctype = eval(ctype)
fields.append((name, ctype))
class Inner(c.Structure, PrettyPrinter):
_fields_ = fields
inner = Inner.from_address(c.addressof(self._buffer))
setattr(self, name, getattr(inner, name))
self = inner
return self

def pack(self):
fields = []
for name, ctype in self._inner_fields:
if type(ctype) == str:
ctype = eval(ctype)
fields.append((name, ctype))
class Inner(c.Structure, PrettyPrinter):
_fields_ = fields
inner = Inner()
for name, ctype in self._inner_fields:
value = getattr(self, name)
if type(value) == list:
l = getattr(inner, name)
for i in range(len(l)):
l[i] = getattr(self, name)[i]
else:
setattr(inner, name, value)
return inner

它看起来应该可以工作,但是当我运行它时出现错误:TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of its all its bases

我搜索了解决此问题的提示,但 ctypes 结构看起来是在 c 库中实现的。我不确定如何解决此问题,感谢任何帮助或具体解决方案!

最佳答案

问题是 ctypes.Structure 使用了它自己的自定义元类:_ctypes.StructType。由于您从 Structure 继承元类,Python 不知道在构造您的类时使用哪个元类。

您可以通过从 _ctypes.StructType 继承您的元类来解决这个问题。由于元类的名称是 ctypes 模块的实现细节,我建议编写 type(ctypes.Structure) 以动态获取元类。

import ctypes

class VariableMeta(type(ctypes.Structure)):
pass

这种方法的缺点是您限制了元类的使用。如果您只打算将它用于 ctypes.Structure 的子类,这可能没问题。

另一种方法是创建一个从两个元类继承的中间元类。

class PointsMetaClass(type(ctypes.Structure), VariableMeta):
pass

class Points(c.Structure, metaclass=PointsMetaClass):
# ...

始终确保在元类的 __new__ 中使用 super() 而不是硬编码 type!

return super(VariableMeta, cls).__new__(cls, name, bases, dct)

Guido 曾经写道:在 Python 中编写元类 will cause your head to explode !

关于python - 元类与 ctypes 结构冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7149488/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com