Есть ли лучший способ получить названную серию констант (перечисление) в Python?
Просто посмотрим на способы получения именных констант в python.
class constant_list:
(A_CONSTANT, B_CONSTANT, C_CONSTANT) = range(3)
Тогда, конечно, вы можете ссылаться на него так:
constant_list.A_CONSTANT
Я полагаю, вы могли бы использовать словарь, используя строки:
constant_dic = {
"A_CONSTANT" : 1,
"B_CONSTANT" : 2,
"C_CONSTANT" : 3,}
и ссылайтесь на него следующим образом:
constant_dic["A_CONSTANT"]
Поэтому мой вопрос прост. Есть ли лучшие способы сделать это? Не сказать, что они неадекватны или что-то еще, просто любопытно - любые другие распространенные идиомы, которые я пропустил?
Спасибо заранее.
Ответы
Ответ 1
В течение 2,3 или после:
class Enumerate(object):
def __init__(self, names):
for number, name in enumerate(names.split()):
setattr(self, name, number)
Для использования:
codes = Enumerate('FOO BAR BAZ')
codes.BAZ
будет равно 2 и так далее.
Если у вас есть только 2.2, перед этим:
from __future__ import generators
def enumerate(iterable):
number = 0
for name in iterable:
yield number, name
number += 1
(Это было взято из здесь)
Ответ 2
Я нашел рецепт класса перечисления (Active State, Python Cookbook), чтобы быть очень эффективным.
Плюс у него есть функция поиска, которая хороша.
PEV
Ответ 3
Альтернативная конструкция для константы:
constants = ["A_CONSTANT", "B_CONSTANT", "C_CONSTANT"]
constant_dic = dict([(c,i) for i, c in enumerate(constants)])
Ответ 4
Следующие действия, такие как classisc "написано на камне" C enum - как только это определено, вы не можете его изменить, вы можете читать только его значения. Вы также не можете создать экземпляр. Все, что вам нужно сделать, это "import enum.py" и получить из класса 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!")
Это тестовый код:
# 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...)"
Ответ 5
Это лучшее, что я видел: "Первичный класс в Python"
http://code.activestate.com/recipes/413486/
Он дает вам класс, и класс содержит все перечисления. Перечисления можно сравнивать друг с другом, но не имеют какой-либо особой ценности; вы не можете использовать их как целочисленное значение. (Сначала я сопротивлялся этому, потому что я привык к C перечислениям, которые являются целыми значениями. Но если вы не можете использовать его как целое число, вы не можете использовать его как целое по ошибке, поэтому в целом я думаю, что это победа.) Каждое перечисление является уникальным объектом. Вы можете печатать перечисления, вы можете перебирать их, вы можете проверить, что значение перечисления "включено" в перечисление. Это довольно полный и гладкий.
Ответ 6
В Python строки неизменяемы и поэтому они лучше для констант, чем числа. Лучший подход, на мой взгляд, состоит в том, чтобы создать объект, который хранит константы в виде строк:
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)
Затем вы можете использовать его следующим образом:
>>> 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