题
这是一些代码,我在互联网上找到。我不知道它是怎样来使用。我只是充满的成员的用枚举键/值和它的作品,但我很好奇这个元类是什么一回事。我假设它是与ctypes的,但我不能找到子类ctypes的很多信息。我知道EnumerationType没有做任何事情,我用枚举的方式。
from ctypes import *
class EnumerationType(type(c_uint)):
def __new__(metacls, name, bases, dict):
if not "_members_" in dict:
_members_ = {}
for key,value in dict.items():
if not key.startswith("_"):
_members_[key] = value
dict["_members_"] = _members_
cls = type(c_uint).__new__(metacls, name, bases, dict)
for key,value in cls._members_.items():
globals()[key] = value
return cls
def __contains__(self, value):
return value in self._members_.values()
def __repr__(self):
return "<Enumeration %s>" % self.__name__
class Enumeration(c_uint):
__metaclass__ = EnumerationType
_members_ = {}
def __init__(self, value):
for k,v in self._members_.items():
if v == value:
self.name = k
break
else:
raise ValueError("No enumeration member with value %r" % value)
c_uint.__init__(self, value)
@classmethod
def from_param(cls, param):
if isinstance(param, Enumeration):
if param.__class__ != cls:
raise ValueError("Cannot mix enumeration members")
else:
return param
else:
return cls(param)
def __repr__(self):
return "<member %s=%d of %r>" % (self.name, self.value, self.__class__)
And an enumeration probably done the wrong way.
class TOKEN(Enumeration):
_members_ = {'T_UNDEF':0, 'T_NAME':1, 'T_NUMBER':2, 'T_STRING':3, 'T_OPERATOR':4, 'T_VARIABLE':5, 'T_FUNCTION':6}
解决方案
一个元类是用于创建类的类。认为它是这样的:所有对象都有一个类,类也是一个对象,因此,是非常有意义的一类可具有类
http://www.ibm.com/developerworks/linux /library/l-pymeta.html
要了解这是什么做的,你可以看看在代码中的几个要点。
_members_ = {'T_UNDEF':0, 'T_NAME':1, 'T_NUMBER':2, 'T_STRING':3, 'T_OPERATOR':4, 'T_VARIABLE':5, 'T_FUNCTION':6}
globals()[key] = value
这需要每个定义的关键在你的字典里:“T_UNDEF”“T_NUMBER”,使他们在你的字典全局可用
。def __init__(self, value):
for k,v in self._members_.items():
if v == value:
self.name = k
break
当你让你的枚举的一个实例,它会检查,看看是否“价值”是你允许的枚举名称列表,当你初始化类。当该值被发现,它设置字符串名称self.name。
c_uint.__init__(self, value)
这是其中设置了“ctypes的值”到实际的C无符号整数的实际线路。
其他提示
这确实是一个奇怪的类。
你正在使用它的方式是正确的,虽然另一种方式将是:
class TOKEN(Enumeration):
T_UNDEF = 0
T_NAME = 1
T_NUMBER = 2
T_STRING = 3
T_OPERATOR = 4
T_VARIABLE = 5
T_FUNCTION = 6
(这就是第一6行中__new__
是)
然后可以用它像这样:
>>> TOKEN
<Enumeration TOKEN>
>>> TOKEN(T_NAME)
<member T_NAME=1 of <Enumeration TOKEN>>
>>> T_NAME in TOKEN
True
>>> TOKEN(1).name
'T_NAME'
在from_param
方法似乎是为了方便起见,用于编写接受任一个int或Enumeration
对象的方法。如果这是真的它的目的不是真的知道。
我觉得这个类是指具有的外部API使用C风格的枚举工作时使用,但它看起来像一个整体工作很多非常小的收益。
不隶属于 StackOverflow