Anulando el método Enum __call__

Tengo un Enum como

 from enum import Enum class Animal(Enum): cat = 'meow' dog = 'woof' never_heard_of = None def talk(self): print(self.value) 

Me gustaría anular el método __call__ para que una llamada como Animal('hee-haw') devuelva Animals.never_heard_of o None lugar de boost ValueError . Preferiría evitar una statement de try cada vez que llamo al Animal .

¿Cuál sería un equivalente Python puro de Enum.__call__ ?

Actualización 2017-03-30

Con Python 3.6 (y aenum 2.0 1 ) puede especificar un método _missing_ que se llamará para darle a su clase una última oportunidad antes de elevar ValueError . Así que ahora puedes hacer:

  @classmethod def _missing_(cls, name): return cls.never_heard_of 

Respuesta original

Para que quede claro: desea que el __call__ que está asociado con Animal() que está realmente en la metaclase ( EnumMeta en enum.py ).

Esta es una bolsa de gusanos a los que no quieres entrar, ya que es muy fácil romper cosas.

Consulta esta respuesta para obtener más detalles, pero la solución simple es crear un método de get para tu enumeración Animal :

  @classmethod def get(cls, name): try: return cls[name] except KeyError: return cls.never_heard_of 

y luego Animal.get('wolf') devolverá Animal.never_heard_of .


1 Divulgación: Soy el autor de Python stdlib Enum , el enum34 backport y la biblioteca de enumeración avanzada ( aenum ) .