我最近阅读了一些关于元类的 SO 问题,虽然它似乎大部分时间都没有必要使用(包括我的问题),但我认为它对这种情况很有趣。
在 struct 的 python 文档中,这里有一个 namedtuple 的例子:
from collections import namedtuple
Student = namedtuple('Student', 'name serialnum school gradelevel')
Student._make(unpack('<10sHHb', record))
我的问题是:是否可以创建一个元类来为我完成其中的一部分?就像我预期的解决方案是:
class Student(object):
__metaclass__ = ???
fields = 'name serialnum school gradelevel'
struct = '<10sHHb'
s = Student(record) # and give same output as the _make() call above
我该怎么做?
最佳答案
绝对是一个有趣的问题,这是我的解决方案:
import struct
import collections
class MetaStruct(type):
def __new__(cls, clsname, bases, dct):
nt = collections.namedtuple(clsname, dct['fields'])
def new(cls, record):
return super(cls, cls).__new__(cls, *struct.unpack(dct['struct'], record))
dct.update(__new__=new)
return super(MetaStruct, cls).__new__(cls, clsname, (nt,), dct)
class Student(object):
__metaclass__ = MetaStruct
fields = 'name serialnum school gradelevel'
struct = '<10sHHb'
record = 'raymond \x32\x12\x08\x01\x08'
s = Student(record)
我的回答和其他人的显着区别是在这个 Student
的末尾仍然是一个类并且s
是 Student
的实例(isinstance(s, Student)
返回真)。我通过让元类将 namedtuple 添加为新创建类的基类来实现这一点,并将新类 ( Student.__new__
) 的对象创建委托(delegate)给基类 (namedtuple)。
关于python - 创建元类以将结构解压到命名元组中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21563298/