Is there a better way to get a named series of constants (enumeration) in Python?
本问题已经有最佳答案,请猛点这里访问。
只是看看在Python中获取命名常量的方法。
1 2 | class constant_list: (A_CONSTANT, B_CONSTANT, C_CONSTANT) = range(3) |
当然,你可以这样称呼它:
1 | constant_list.A_CONSTANT |
我想你可以用字典,用字符串:
1 2 3 4 | constant_dic = { "A_CONSTANT" : 1, "B_CONSTANT" : 2, "C_CONSTANT" : 3,} |
像这样引用它:
1 | constant_dic["A_CONSTANT"] |
那么,我的问题很简单。有更好的方法吗?不是说这些不充分,或者说什么,只是好奇——还有我遗漏的其他常见的习语吗?
事先谢谢。
对于2.3或之后:
1 2 3 4 | class Enumerate(object): def __init__(self, names): for number, name in enumerate(names.split()): setattr(self, name, number) |
使用:
1 | codes = Enumerate('FOO BAR BAZ') |
如果您只有2.2,请在此之前加上:
1 2 3 4 5 6 7 | from __future__ import generators def enumerate(iterable): number = 0 for name in iterable: yield number, name number += 1 |
(这是从这里拿的)
这是我见过的最好的一个:"Python中的第一类枚举"
http://code.activestate.com/recipes/413486/
它为您提供一个类,并且该类包含所有枚举。枚举可以相互比较,但没有任何特定的值;不能将它们用作整数值。(一开始我抵制这个,因为我习惯于C枚举,这是整数值。但是,如果不能将它用作整数,就不能错误地将它用作整数,所以总的来说,我认为这是一个胜利。)每个枚举都是一个唯一的对象。可以打印枚举,可以对其进行迭代,可以测试枚举值是否在枚举中。它很完整,很光滑。
下面的行为类似于Classisc"用石头编写"C枚举——一旦定义好,就不能更改它,只能读取它的值。你也不能实例化它。您所要做的就是"import enum.py"并从类枚举派生。
1 2 3 4 5 6 7 8 9 10 11 12 13 | # 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!") |
这是测试代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | # 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...)" |
常数dic的另一种构造:
1 2 | constants = ["A_CONSTANT","B_CONSTANT","C_CONSTANT"] constant_dic = dict([(c,i) for i, c in enumerate(constants)]) |
我发现枚举类配方(活动状态、python食谱)非常有效。
另外,它还有一个查找功能,很好。
聚戊酸乙烯酯
在python中,字符串是不可变的,因此它们对于常量比数字更好。在我看来,最好的方法是制作一个将常量保持为字符串的对象:
1 2 3 4 5 6 7 8 9 10 11 | 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) |
然后您可以这样使用它:
1 2 3 4 5 6 7 8 9 10 11 12 | >>> 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 |