¿Cómo se pueden obtener los miembros de un Enum en el espacio de nombres global?

Python ahora tiene un tipo Enum (nuevo en 3.4 con PEP 435 y alse backported ), y mientras que los espacios de nombres son una buena cosa, a veces las Enums se usan más como constantes, y los miembros de la enumeración deben vivir en el espacio de nombres global (er, module) .

Así que en lugar de:

Constant(Enum): PI = 3.14 ... area = Constant.PI * r * r 

Solo puedo decir:

 area = PI * r * r 

¿Hay una manera fácil de llegar de Constant.PI a PI ?

El método soportado oficialmente es algo como esto:

 globals().update(Constant.__members__) 

Esto funciona porque __members__ es el objeto similar a dict que contiene los nombres y miembros de la clase Enum.

Personalmente me parece lo suficientemente feo como para agregar el siguiente método a mis clases Enum:

 @classmethod def export_to(cls, namespace): namespace.update(cls.__members__) 

y luego en mi código de nivel superior puedo decir:

 Constant.export_to(globals()) 

Nota: exportar un Enum al espacio de nombres global solo funciona bien cuando el módulo solo tiene un Enum exportado. Si tiene varios, es mejor tener un alias más corto para el Enum mismo, y usarlo en lugar de contaminar el espacio de nombres global:

 class Constant(Enum): PI = .... C = Constant area = C.PI * r * r 

FWIW: esto es más un comentario que una respuesta. A continuación se muestra el comienzo de una función de un código antiguo que escribí que implementa sus propios objetos con nombre int -like-enumerados que se agregaron al espacio de nombres global de forma predeterminada (no hay contenedor denominado Enum class involucrada). Sin embargo, está haciendo algo similar a lo que se muestra en su propia respuesta, así que creo que es un buen enfoque general porque me ha funcionado bien.

 def Enum(names, values=None, namespace=None): """Function to assign values to names given and add them to a namespace. Default values are a sequence of integers starting at zero. Default namespace is the caller's globals.""" if namespace is None: namespace = sys._getframe(1).f_globals # caller's globals pairs = _paird(names, values) namespace.update(pairs) # bind names to cooresponding named numbers . . . 

El punto es que, en lo que respecta a la implementación de algo para el módulo de clase Enum actual, sugeriría agregar algo parecido o el def export_to() que se muestra en su propia respuesta a la clase base Enum en la próxima versión de Python para que esté disponible automáticamente.