python enumeration_python模块之enum_上
enum模塊定義了:
4種枚舉類:Enum, IntEnum, Flag, IntFlag
裝飾器:unique()
助手:auto
Flag, IntFlag, auto在python3.6中加入
創(chuàng)建枚舉
from enum import Enum
class Color(Enum):
RED = 2
GREEN = 4
BLUE = 6
注意點:
1. 枚舉值可以是任何類型,如果值不重要可以使用auto()自動選擇。但在有其他已定義的值的情況下,謹慎與auto混用
2. Color是枚舉類,Color.RED等是枚舉成員,枚舉成員擁有name和value屬性
3. 雖然使用class關(guān)鍵字創(chuàng)建,但枚舉并不是常規(guī)意義上的python類
枚舉成員的展現(xiàn)形式:
>>>print(Color.RED)
Color.RED
>>>print(repr(Color.RED))
枚舉成員的type類型是其所屬的枚舉類:
>>>type(Color.RED)
>>>isinstance(Color.RED, Color)
True
枚舉支持按照定義時的順序進行迭代:
>>>for color in Color:
... print(color)
...
Color.RED
Color.GREEN
Color.BLUE
枚舉成員是可哈希的,因此可以在字典和集合中使用:
>>> apples = {}
>>> apples[Color.RED] = 'red delicious'
>>> apples[Color.GREEN] = 'granny smith'
>>> apples == {Color.RED: 'red delicious', Color.GREEN: 'granny smith'}
True
對枚舉成員及其屬性的程序化訪問
通過值訪問枚舉成員:
>>>Color(2)
通過名稱訪問枚舉成員:
>>>Color["RED"]
獲取枚舉成員的名稱和值:
>>>member = Color.RED
>>>member.name
"RED"
>>>member.value
2
枚舉成員及其值的重復(fù)性問題
擁有兩個相同名稱的枚舉成員是不允許的:
>>> class Shape(Enum):
... SQUARE = 2
... SQUARE = 3
...
Traceback (most recent call last):
...
TypeError: Attempted to reuse key: 'SQUARE'
不過不同的枚舉成員允許擁有相同的值。后定義的成員是先定義的成員的別名,通過值或名稱訪問時都將返回先定義的成員:
>>> class Shape(Enum):
... SQUARE = 2
... DIAMOND = 1
... CIRCLE = 3
... ALIAS_FOR_SQUARE = 2
...
>>> Shape.SQUARE
>>> Shape.ALIAS_FOR_SQUARE
>>> Shape(2)
注意點:任意兩個枚舉屬性(包括成員、方法等)不允許存在相同的名稱
枚舉值唯一約束
默認情況下,允許多個成員擁有相同的值。使用unique裝飾器可以對枚舉值進行唯一約束
@enum.unique: 枚舉專用的類裝飾器。它在枚舉的__members__屬性中只要查找到成員別名就拋出ValueError異常
>>> from enum import Enum, unique
>>> @unique
... class Mistake(Enum):
... ONE = 1
... TWO = 2
... THREE = 3
... FOUR = 3
...
Traceback (most recent call last):
...
ValueError: duplicate values found in : FOUR -> THREE
自動生成枚舉值
對于不重要的枚舉值,可以使用auto自動生成:
>>> from enum import Enum, auto
>>> class Color(Enum):
... RED = auto()
... BLUE = auto()
... GREEN = auto()
...
>>> list(Color)
[, , ]
auto生成什么值取決于_generate_next_value_()方法,可重寫:
>>> class AutoName(Enum):
... def _generate_next_value_(name, start, count, last_values):
... return name
...
>>> class Ordinal(AutoName):
... NORTH = auto()
... SOUTH = auto()
... EAST = auto()
... WEST = auto()
...
>>> list(Ordinal)
[, , , ]
迭代
對枚舉成員的迭代,并不會包含成員別名:
>>> list(Shape)
[, , ]
__members__屬性是一個映射了枚舉成員及其名稱的有序字典,包括成員別名:
>>> for name, member in Shape.__members__.items():
... name, member
...
('SQUARE', )
('DIAMOND', )
('CIRCLE', )
('ALIAS_FOR_SQUARE', )
>>> [name for name, member in Shape.__members__.items() if member.name != name]
['ALIAS_FOR_SQUARE']
枚舉比較(后兩種不適用于IntEnum)
>>> Color.RED is Color.RED
True
>>> Color.RED == Color.BLUE
False
>>> Color.RED < Color.BLUE
Traceback (most recent call last):
File "", line 1, in
TypeError: '
>>> Color.BLUE == 6 # 與非枚舉的值進行等值比較總是返回False
False
允許的枚舉成員與屬性
枚舉是python類,也可以擁有普通方法和特殊方法:
class Mood(Enum):
FUNKY = 1
HAPPY = 3
def describe(self):
# self is the member here
return self.name, self.value
def __str__(self):
return 'my custom str! {0}'.format(self.value)
@classmethod
def favorite_mood(cls):
# cls here is the enumeration
return cls.HAPPY
注意點:如果枚舉中定義了__new()__或者__init__()方法,賦值給枚舉成員的值將被傳遞到__new()__或者__init__()中
枚舉的繼承限制
自定義枚舉類必須繼承自一個枚舉基類,至多一個具體的數(shù)據(jù)類型以及0至多個混合類。繼承順序如下:
class EnumName([mix-in, ...,] [data-type,] base-enum):
pass
基類枚舉如果已經(jīng)定義了成員,則不能被任何子類繼承,如下第一種是不允許的,但第二種可以:
>>> class MoreColor(Color):
... PINK = 17
...
Traceback (most recent call last):
...
TypeError: Cannot extend enumerations
>>> class Foo(Enum):
... def some_behavior(self):
... pass
...
>>> class Bar(Foo):
... HAPPY = 1
... SAD = 2
...
不能這么做的原因是可能破壞某些重要的不允許改變的值(原話是would lead to a violation of some important invariants of bytes and instances)。
序列化
>>> from a.b import Color
>>> from pickle import dumps, loads
>>> Color.RED is loads(dumps(Color.RED))
True
一般要求序列化的枚舉要定義在模塊頂層,因為反序列化要求枚舉能夠從模塊導(dǎo)入。不過在第4版的pickle協(xié)議中,已經(jīng)可以序列化嵌套在類中的枚舉
通過在枚舉中定義__reduce_ex__()方法,可以修改枚舉成員的序列化/反序列化行為
Functional API
枚舉類是可調(diào)用的:
>>> Animal = Enum("Pet", "Tortoise CAT DOG")
完整的API如下:
Enum(value='NewEnumName', names=<...>, *, module='...', qualname='...', type=, start=1)
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的python enumeration_python模块之enum_上的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 同校生2怎么玩
- 下一篇: websocket python爬虫_p