2009-12-01 6 views
2

Dans l'exemple de code d'énumération donnée dans this question, reproduit ci-dessous, pourquoi TOKEN contiennent les implémentations de __contains__ et __repr__ de la métaclasse EnumerationType?méthodes Hériter d'une métaclasse

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} 

j'attendre d'avoir des exceptions lancées par le code suivant à l'effet que __contains__ n'est pas mis en œuvre, au lieu cependant, je reçois True False.

print 2 in TOKEN, 7 in TOKEN 

Répondre

2

Les deux Enumeration et TOKEN sont des instances de EnumerationType:

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

Et special methods for instances of new style classes are looked up in class, par exemple repr(TOKEN) est équivalent à type(TOKEN).__repr__(TOKEN), qui est EnumerationType.__repr__(TOKEN).

+0

Je viens juste de comprendre votre réponse maintenant. spécifiquement 'dans TOKEN' est d'appeler' __contains__' sur la classe 'TOKEN', et comme' Token' est une instance de 'EnumerationType', sa méthode spéciale peut être appelée. –

Questions connexes