2009-12-01 141 views
2

在下面转载的this question中给出的示例枚举代码中,为什么TOKEN包含元类EnumerationType中的__contains____repr__的实现?从元类继承方法

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__) 

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} 

我希望有通过下面的代码到__contains__不落实的效果抛出的异常,而不是然而,我收到True False

print 2 in TOKEN, 7 in TOKEN 

回答

2

两个EnumerationTOKENEnumerationType实例:

>>> isinstance(Enumeration, EnumerationType) 
True 
>>> isinstance(TOKEN, EnumerationType) 
True 

special methods for instances of new style classes are looked up in class而且,例如repr(TOKEN)相当于type(TOKEN).__repr__(TOKEN),即EnumerationType.__repr__(TOKEN)

+0

我只是现在才明白你的答案。具体来说'在TOKEN'中调用类'TOKEN'上的'__contains__',而'Token'是'EnumerationType'的一个实例,可以调用它的特殊方法。 – 2009-12-02 09:32:07