How can I represent an 'Enum' in Python?
I'm mainly a C# developer, but I'm currently working on a project in Python.
How can I represent the equivalent of an Enum in Python?
Enums have been added to Python 3.4 as described in PEP 435. It has also been backported to 3.3, 3.2, 3.1, 2.7, 2.6, 2.5, and 2.4 on pypi.
For more advanced Enum techniques try the aenum library (2.7, 3.3+, same author as enum34
. Code is not perfectly compatible between py2 and py3, eg you'll need __order__
in python 2).
enum34
, do $ pip install enum34
aenum
, do $ pip install aenum
Installing enum
(no numbers) will install a completely different and incompatible version.
from enum import Enum # for enum34, or the stdlib version
# from aenum import Enum # for the aenum version
Animal = Enum('Animal', 'ant bee cat dog')
Animal.ant # returns <Animal.ant: 1>
Animal['ant'] # returns <Animal.ant: 1> (string lookup)
Animal.ant.name # returns 'ant' (inverse lookup)
or equivalently:
class Animal(Enum):
ant = 1
bee = 2
cat = 3
dog = 4
In earlier versions, one way of accomplishing enums is:
def enum(**enums):
return type('Enum', (), enums)
which is used like so:
>>> Numbers = enum(ONE=1, TWO=2, THREE='three')
>>> Numbers.ONE
1
>>> Numbers.TWO
2
>>> Numbers.THREE
'three'
You can also easily support automatic enumeration with something like this:
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
return type('Enum', (), enums)
and used like so:
>>> Numbers = enum('ZERO', 'ONE', 'TWO')
>>> Numbers.ZERO
0
>>> Numbers.ONE
1
Support for converting the values back to names can be added this way:
def enum(*sequential, **named):
enums = dict(zip(sequential, range(len(sequential))), **named)
reverse = dict((value, key) for key, value in enums.iteritems())
enums['reverse_mapping'] = reverse
return type('Enum', (), enums)
This overwrites anything with that name, but it is useful for rendering your enums in output. It will throw KeyError if the reverse mapping doesn't exist. With the first example:
>>> Numbers.reverse_mapping['three']
'THREE'
Before PEP 435, Python didn't have an equivalent but you could implement your own.
Myself, I like keeping it simple (I've seen some horribly complex examples on the net), something like this ...
class Animal:
DOG = 1
CAT = 2
x = Animal.DOG
In Python 3.4 (PEP 435), you can make Enum the base class. This gets you a little bit of extra functionality, described in the PEP. For example, enum values are distinct from integers.
class Animal(Enum):
DOG = 1
CAT = 2
print(Animal.DOG)
<Animal.DOG: 1>
If you don't want to type the values, use the following shortcut:
class Animal(Enum):
DOG, CAT = range(2)
Here is one implementation:
class Enum(set):
def __getattr__(self, name):
if name in self:
return name
raise AttributeError
Here is its usage:
Animals = Enum(["DOG", "CAT", "HORSE"])
print(Animals.DOG)
链接地址: http://www.djcxy.com/p/2666.html
上一篇: 在JavaScript中定义枚举的首选语法是什么?
下一篇: 我如何在Python中表示'Enum'?