color - python plotly axis
¿Hay una mejor manera de obtener una serie de constantes nombradas(enumeración) en Python? (6)
Esta pregunta ya tiene una respuesta aquí:
- ¿Cómo puedo representar un ''Enum'' en Python? 43 respuestas
Solo buscando formas de obtener constantes con nombre en Python.
class constant_list:
(A_CONSTANT, B_CONSTANT, C_CONSTANT) = range(3)
Entonces, por supuesto, puede referirse a él de esta manera:
constant_list.A_CONSTANT
Supongo que podrías usar un diccionario, usando cadenas:
constant_dic = {
"A_CONSTANT" : 1,
"B_CONSTANT" : 2,
"C_CONSTANT" : 3,}
y refiérete a esto así:
constant_dic["A_CONSTANT"]
Mi pregunta, entonces, es simple. ¿Hay alguna forma mejor de hacer esto? No digo que estos sean inadecuados ni nada, solo curiosidad, ¿algún otro modismo común que me haya perdido?
Gracias por adelantado.
En Python, las cadenas son inmutables, por lo que son mejores para las constantes que para los números. El mejor enfoque, en mi opinión, es crear un objeto que mantenga constantes como cadenas:
class Enumeration(object):
def __init__(self, possibilities):
self.possibilities = set(possibilities.split())
def all(self):
return sorted(self.possibilities)
def __getattr__(self, name):
if name in self.possibilities:
return name
raise AttributeError("Invalid constant: %s" % name)
Podrías usarlo así:
>>> enum = Enumeration("FOO BAR")
>>> print enum.all()
[''BAR'', ''FOO'']
>>> print enum.FOO
FOO
>>> print enum.FOOBAR
Traceback (most recent call last):
File "enum.py", line 17, in <module>
print enum.FOOBAR
File "enum.py", line 11, in __getattr__
raise AttributeError("Invalid constant: %s" % name)
AttributeError: Invalid constant: FOOBAR
Encuentro que la receta de la clase de enumeración (Estado Activo, Cookbook de Python ) es muy efectiva.
Además, tiene una función de búsqueda que es agradable.
Pev
Para 2.3 o después:
class Enumerate(object):
def __init__(self, names):
for number, name in enumerate(names.split()):
setattr(self, name, number)
Usar:
codes = Enumerate(''FOO BAR BAZ'')
codes.BAZ
será 2 y así sucesivamente.
Si solo tiene 2.2, preceda esto con:
from __future__ import generators
def enumerate(iterable):
number = 0
for name in iterable:
yield number, name
number += 1
( Esto fue tomado de aquí )
Una construcción alternativa para constant_dic:
constants = ["A_CONSTANT", "B_CONSTANT", "C_CONSTANT"]
constant_dic = dict([(c,i) for i, c in enumerate(constants)])
Lo siguiente actúa como una clase clasica "escrita en piedra": una vez definida, no puedes cambiarla, solo puedes leer sus valores. Tampoco puedes instanciarlo. Todo lo que tienes que hacer es "importar enum.py" y derivar de la clase Enum.
# this is enum.py
class EnumException( Exception ):
pass
class Enum( object ):
class __metaclass__( type ):
def __setattr__( cls, name, value ):
raise EnumException("Can''t set Enum class attribute!")
def __delattr__( cls, name ):
raise EnumException("Can''t delete Enum class attribute!")
def __init__( self ):
raise EnumException("Enum cannot be instantiated!")
Este es el código de prueba:
# this is testenum.py
from enum import *
class ExampleEnum( Enum ):
A=1
B=22
C=333
if __name__ == ''__main__'' :
print "ExampleEnum.A |%s|" % ExampleEnum.A
print "ExampleEnum.B |%s|" % ExampleEnum.B
print "ExampleEnum.C |%s|" % ExampleEnum.C
z = ExampleEnum.A
if z == ExampleEnum.A:
print "z is A"
try:
ExampleEnum.A = 4
print "ExampleEnum.A |%s| FAIL!" % ExampleEnum.A
except EnumException:
print "Can''t change Enum.A (pass...)"
try:
del ExampleEnum.A
except EnumException:
print "Can''t delete Enum.A (pass...)"
try:
bad = ExampleEnum()
except EnumException:
print "Can''t instantiate Enum (pass...)"
Este es el mejor que he visto: "Enumeraciones de primera clase en Python"
http://code.activestate.com/recipes/413486/
Te da una clase, y la clase contiene todas las enumeraciones. Las enumeraciones se pueden comparar entre sí, pero no tienen ningún valor particular; no puedes usarlos como un valor entero. (He resistido esto al principio porque estoy acostumbrado a C enums, que son valores enteros. Pero si no puedes usarlo como un entero, no puedes usarlo como un entero por error, así que, en general, creo que es un triunfo .) Cada enum es un objeto único. Puede imprimir enumeraciones, puede iterar sobre ellas, puede probar que un valor enum está "en" la enumeración. Es bastante completo y resbaladizo.