切换菜单
搜索
个人笔记云
首页
java
spring
springmvc
python
使用教程
笔记管理
搜索
登录/注册
好物分享
退出
搜索
python中如何定义枚举常量 枚举 python
2023-12-05
631
[原文链接]() # python中如何定义枚举常量 枚举 python enum模块可以定义具有迭代和比较能力的枚举类型。它可以为各个值创建具有明确意义的符号标记,而不是使用整数或者字符串。 ### python的枚举类的特殊属性name和value 在定义python枚举是,当我们定义枚举对象的成员对象时,一定要切记,name和value这个两个属性已经默认被python 枚举默认占用,我们不能再次定义,否则就会冲突,例如如下: ``` import enum class LinkTagEnum(enum.Enum): """ 连接类型的标签值 """ general = {'code':'general',"text":'普通类型'} cover_image = {'code':'cover_image',"text":'封面图片'} def __init__(self,vals): self.code = vals["code"] self.text = vals['text'] # 下面的写法是错误的 # self.name = vals["code"] # self.value = vals['text'] ``` ### 创建枚举类型 一个新的枚举类型使用类语法,通过继承Enum类,并且在类中添加类属性来描述各个值。 **enum_create.py** ``` 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('\nMember name: {}'.format(BugStatus.wont_fix.name)) print('Member value: {}'.format(BugStatus.wont_fix.value)) ``` Enum的各个成员被转换成实例。每一个实例具有一个name属性,即我们定义的属性名称,还具有一个value属性,即我们给属性赋的值。 ``` $ python3 enum_create.py Member name: wont_fix Member value: 4 ``` ### 迭代 枚举类的迭代可以产生每一个单独的枚举变量。 **enum_iterate.py** ``` 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)) ``` 成员产生的顺序与它们在类中声明的顺序一致。name和value的值并不会影响这个顺序。 ``` $ python3 enum_iterate.py new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1 ``` ### 比较枚举变量 因为枚举类的成员并没有顺序,所以他们只支持对象身份比较和相等比较。 **enum_comparison.py** ``` 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('\n'.join(' ' + s.name for s in sorted(BugStatus))) except TypeError as err: print(' Cannot sort: {}'.format(err)) ``` 大于和小于的比较将会引发TypeError异常。 ``` $ python3 enum_comparison.py Equality: False True Identity: False True Ordered by value: Cannot sort: unorderable types: BugStatus() < BugStatus() ``` 使用IntEnum类将会让枚举类型的成员表现得更像数字类型,比如,他们支持排序。 **enum_intenum.py** ``` 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('\n'.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 ``` ### 唯一的枚举值 具有相同值的枚举成员被看做是同一个对象的不同别名引用。别名也不会引起枚举类的迭代器出现重复值。 **enum_aliases.py** ``` import enum class BugStatus(enum.Enum): new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1 by_design = 4 closed = 1 for status in BugStatus: print('{:15} = {}'.format(status.name, status.value)) print('\nSame: by_design is wont_fix: ', BugStatus.by_design is BugStatus.wont_fix) print('Same: closed is fix_released: ', BugStatus.closed is BugStatus.fix_released) ``` 因为by_design和closed是另外一些成员的别名,所以它们在我们迭代这个枚举类的时候并不会出现。成员的名字被认为是第一个关联到这个值的名字。 ``` $ python3 enum_aliases.py new = 7 incomplete = 6 invalid = 5 wont_fix = 4 in_progress = 3 fix_committed = 2 fix_released = 1 Same: by_design is wont_fix: True Same: closed is fix_released: True ``` 如果我们需要枚举成员具有唯一的值,可以给枚举类添加@unique`装饰器。 **enum_unique_enforce.py** ``` 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 ``` 当枚举类被解释执行的时候,如果成员具有重复的值,将会引发ValueError异常。 ``` $ python3 enum_unique_enforce.py Traceback (most recent call last): File "enum_unique_enforce.py", line 11, in
class BugStatus(enum.Enum): File ".../lib/python3.5/enum.py", line 573, in unique (enumeration, alias_details)) ValueError: duplicate values found in
: by_design -> wont_fix, closed -> fix_released ``` ### 程序化创建枚举类 在一些情况下,通过程序化创建枚举类比将它们硬编码到一个类中更加方便。在这些场景中,枚举类允许将成员名字和对应的值传递给类的构造方法。 **enum_programmatic_create.py** ``` 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('\nAll members:') for status in BugStatus: print('{:15} = {}'.format(status.name, status.value)) ``` value参数是枚举类的名称,用来创建枚举成员的表述说明。names参数列出了枚举类的所有成员。如果传递的是一个单独的字符串,那么它会用空格或者逗号分隔开,分隔后的结果字符串用作成员名字,并且从1开始,自动给每个成员分配一个值。 ``` $ 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 ``` 想要对名字和值进行更多的控制,可以给names传递一个包含两个元素的元组的序列或者一个字典。 **enum_programmatic_mapping.py** ``` 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)) ``` 在这个例子中,我们给names参数传递了一个包含两个元素的元组的列表,而不是一个只包含成员名字的字符串。这样我们就可以通过这种方式创建出和enum_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 ``` ### 非整数成员值 枚举成员值并没有严格限制为整数。实际上,枚举成员可以是任意类型的值。如果值是一个元组,那么成员会作为私有变量传递给__init__()方法。 **enum_tuple_values.py** ``` import enum class BugStatus(enum.Enum): new = (7, ['incomplete', 'invalid', 'wont_fix', 'in_progress']) incomplete = (6, ['new', 'wont_fix']) invalid = (5, ['new']) wont_fix = (4, ['new']) in_progress = (3, ['new', 'fix_committed']) fix_committed = (2, ['in_progress', 'fix_released']) fix_released = (1, ['new']) def __init__(self, num, transitions): self.num = num self.transitions = transitions def can_transition(self, new_state): return new_state.name in self.transitions print('Name:', BugStatus.in_progress) print('Value:', BugStatus.in_progress.value) print('Custom attribute:', BugStatus.in_progress.transitions) print('Using attribute:', BugStatus.in_progress.can_transition(BugStatus.new)) ``` 在这个例子中,每一成员值都一个元组,包含一个数字ID号和一个当前状态可以转换到的状态列表。 ``` $ python3 enum_tuple_values.py Name: BugStatus.in_progress Value: (3, ['new', 'fix_committed']) Custom attribute: ['new', 'fix_committed'] Using attribute: True ``` 对于更复杂的情况,使用元组变得有些笨拙。因为成员值可以是任意类型的对象,所以我们可以使用字典来标识每个成员值中分散的属性。复杂的成员值作为除self参数外唯一的参数直接传递给__init__()方法。 **enum_complex_values.py** ``` import enum class BugStatus(enum.Enum): new = { 'num': 7, 'transitions': [ 'incomplete', 'invalid', 'wont_fix', 'in_progress', ], } incomplete = { 'num': 6, 'transitions': ['new', 'wont_fix'], } invalid = { 'num': 5, 'transitions': ['new'], } wont_fix = { 'num': 4, 'transitions': ['new'], } in_progress = { 'num': 3, 'transitions': ['new', 'fix_committed'], } fix_committed = { 'num': 2, 'transitions': ['in_progress', 'fix_released'], } fix_released = { 'num': 1, 'transitions': ['new'], } def __init__(self, vals): self.num = vals['num'] self.transitions = vals['transitions'] def can_transition(self, new_state): return new_state.name in self.transitions print('Name:', BugStatus.in_progress) print('Value:', BugStatus.in_progress.value) print('Custom attribute:', BugStatus.in_progress.transitions) print('Using attribute:', BugStatus.in_progress.can_transition(BugStatus.new)) ``` 该示例使用字典而不是元组,但是与上个示例有相同的输出。 ``` $ python3 enum_complex_values.py Name: BugStatus.in_progress Value: {'transitions': ['new', 'fix_committed'], 'num': 3} Custom attribute: ['new', 'fix_committed'] Using attribute: True ```
教程分类
热门视频教程
热门文章
热门书籍推荐