enum
某个变量有若干有表征意义的离散值, 则可以考虑使用枚举。
例如系统运行错误码、HTTP状态码。
https://docs.python.org/3.5/library/enum.html
An enumeration is a set of symbolic names (members) bound to unique, constant values. Within an enumeration, the members can be compared by identity, and the enumeration itself can be iterated over.
This module defines two enumeration classes that can be used to define unique sets of names and values:
Enum
andIntEnum
. It also defines one decorator,unique()
.
- class
enum.
Enum
Base class for creating enumerated constants. See section Functional API for an alternate construction syntax.
- class
enum.
IntEnum
Base class for creating enumerated constants that are also subclasses of
int
.
enum.
unique
()Enum class decorator that ensures only one name is bound to any one value.
https://pymotw.com/3/enum/index.html
The
enum
module defines an enumeration type with iteration and comparison capabilities. It can be used to create well-defined symbols for values, instead of using literal integers or strings.
CREATE
类继承定义枚举。
https://pymotw.com/3/enum/index.html
import enum class BugStatus(enum.Enum): new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1 print(' Member name: {}'.format(BugStatus.wont_fix.name)) print('Member value: {}'.format(BugStatus.wont_fix.value))
Creating Enumerations Programmatically
类实例化定义枚举。
import enum BugStatus = enum.Enum( value='BugStatus', names=('fix_released fix_committed in_progress ' 'wont_fix invalid incomplete new'), ) print('Member: {}'.format(BugStatus.new)) print(' All members:') for status in BugStatus: print('{:15} = {}'.format(status.name, status.value))
The
value
argument is the name of the enumeration, which is used to build the representation of members. Thenames
argument lists the members of the enumeration. When a single string is passed, it is split on whitespace and commas, and the resulting tokens are used as names for the members, which are automatically assigned values starting with1
.$ python3 enum_programmatic_create.py Member: BugStatus.new All members: fix_released = 1 fix_committed = 2 in_progress = 3 wont_fix = 4 invalid = 5 incomplete = 6 new = 7
import enum BugStatus = enum.Enum( value='BugStatus', names=[ ('new', 7), ('incomplete', 6), ('invalid', 5), ('wont_fix', 4), ('in_progress', 3), ('fix_committed', 2), ('fix_released', 1), ], ) print('All members:') for status in BugStatus: print('{:15} = {}'.format(status.name, status.value))
In this example, a list of two-part tuples is given instead of a single string containing only the member names. This makes it possible to reconstruct the
BugStatus
enumeration with the members in the same order as the version defined inenum_create.py
.$ python3 enum_programmatic_mapping.py All members: new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1
Iteration
遍历枚举。
import enum class BugStatus(enum.Enum): new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1 for status in BugStatus: print('{:15} = {}'.format(status.name, status.value))
The members are produced in the order they are declared in the class definition. The names and values are not used to sort them in any way.
$ python3 enum_iterate.py new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1
Comparing Enums --- EQUALITY
比较枚举是否相等。
import enum class BugStatus(enum.Enum): new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1 actual_state = BugStatus.wont_fix desired_state = BugStatus.fix_released print('Equality:', actual_state == desired_state, actual_state == BugStatus.wont_fix) print('Identity:', actual_state is desired_state, actual_state is BugStatus.wont_fix) print('Ordered by value:') try: print(' '.join(' ' + s.name for s in sorted(BugStatus))) except TypeError as err: print(' Cannot sort: {}'.format(err))
The greater-than and less-than comparison operators raise
TypeError
exceptions.$ python3 enum_comparison.py Equality: False True Identity: False True Ordered by value: Cannot sort: '<' not supported between instances of 'BugStatus ' and 'BugStatus'
Comparing Enums --- ORDER
比较枚举的大小。
import enum class BugStatus(enum.IntEnum): new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1 print('Ordered by value:') print(' '.join(' ' + s.name for s in sorted(BugStatus)))
$ python3 enum_intenum.py Ordered by value: fix_released fix_committed in_progress wont_fix invalid incomplete new
Unique Enumeration Values
确保枚举值具有唯一性。
import enum @enum.unique class BugStatus(enum.Enum): new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1 # This will trigger an error with unique applied. by_design = 4 closed = 1
Members with repeated values trigger a
ValueError
exception when theEnum
class is being interpreted.$ python3 enum_unique_enforce.py Traceback (most recent call last): File "enum_unique_enforce.py", line 11, in <module> class BugStatus(enum.Enum): File ".../lib/python3.7/enum.py", line 848, in unique (enumeration, alias_details)) ValueError: duplicate values found in <enum 'BugStatus'>: by_design -> wont_fix, closed -> fix_released
星球案例
>>> class Planet(Enum): ... MERCURY = (3.303e+23, 2.4397e6) ... VENUS = (4.869e+24, 6.0518e6) ... EARTH = (5.976e+24, 6.37814e6) ... MARS = (6.421e+23, 3.3972e6) ... JUPITER = (1.9e+27, 7.1492e7) ... SATURN = (5.688e+26, 6.0268e7) ... URANUS = (8.686e+25, 2.5559e7) ... NEPTUNE = (1.024e+26, 2.4746e7) ... def __init__(self, mass, radius): ... self.mass = mass # in kilograms ... self.radius = radius # in meters ... @property ... def surface_gravity(self): ... # universal gravitational constant (m3 kg-1 s-2) ... G = 6.67300E-11 ... return G * self.mass / (self.radius * self.radius) ... >>> Planet.EARTH.value (5.976e+24, 6378140.0) >>> Planet.EARTH.surface_gravity 9.802652743337129