python-枚举库enum

本文详细介绍了Python内置的枚举模块enum,包括枚举的创建、枚举成员的值和名、重复问题、unique装饰器、自动赋值等功能。枚举用于定义常量,具有不可变特性,可用于圆周率等常量的严格定义。枚举成员可以通过名称或值进行访问,可以遍历,但不允许比较大小。文章还提到了基于位掩码的枚举类型enum.Flag。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

为什么需要枚举?枚举是用来定义常量的。枚举元素具有不可变的特性,可以用来充当常量。

枚举是与唯一常量值绑定的一系列符号名称(成员)的集合。枚举中的元素可以进行恒等比较,并且枚举本身可迭代。

例如,对于圆周率,我们在 Python 中简单定义 PI = 3.14,但 PI 是变量,是可以被修改的,故更严格地定义常量需要用到枚举。本文是对 Python 内置枚举模块 enum 的讲解。

注解:枚举成员名称的大小写因为枚举是用来表示常量的,因此,枚举成员名称建议使用大写字母,本文的示例将采用此种风格。

enum及其子类

python的枚举类型是继承enum模块的Enum类,定义自己的枚举类,枚举元素相当于类变量

from enum import Enum

class colorEnum(Enum):
    red = 1
    yellow = 2
    blue = 3
# 方法2:
from enum import Enum
 
Month = Enum('month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

enum模块子类

enum 模块定义了四个枚举类,用来定义名称与值的唯一组合:EnumIntEnumFlagIntFlag。此外,还定义了一个装饰器 unique() 和一个辅助类 auto

  • class enum.Enum:创建枚举常量的基类。
  • class enum.IntEnum:创建 int 子类枚举常量的基类。
  • class enum.Flag:创建可与位运算符搭配使用,而又不失去 Flag 成员资格的枚举常量的基类。
  • class enum.IntFlag:创建可与位运算符搭配使用,而又不失去 IntFlag 成员资格的枚举常量的基类。
  • enum.unique()Enum 类的装饰器,确保一个名称只绑定一个值。
  • class enum.auto:用合适的值代替 Enum 成员的实例。初始默认值从 1 开始。

新建枚举

枚举是用 class 语法创建的,这种方式易读、易写。利用子类 Enum 定义枚举方法如下:

from enum import Enum
class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3
# 方法2:
from enum import Enum
 
Month = Enum('month', ('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'))

注解:Enum 成员值成员值可以是 intstr 等。若无需设定确切值,auto 实例可以自动为成员分配合适的值。将 auto 和其它值混用需慎重。

注解:命名法

  • Color 是枚举(Enum)。
  • Color.REDColor.GREEN 等属性是枚举成员(Enum 成员),也是常量。
  • 枚举成员具有名称和值(例如 Color.RED 的名称为 REDColor.BLUE 的值为3等等)。

注解:虽然 Enumclass 语法创建,但 Enum 并不是常规的 Python 类。

重复问题

value重复

默认情况下,不同的成员值允许相同。但是两个相同值的成员,第二个成员的名称被视作第一个成员的别名

from enum import Enum


class BaseFunc(Enum):
    name = "张三"
    names = "张三"
    age = 25
    sex = '男'


data_name = BaseFunc.name
data_names = BaseFunc.names

print(data_name)
print(data_names)

print(data_name.value)
print(data_names.value)

枚举类型是name=value的形式,name是不能重复,value可以重复,但是重复的值的别名是第一个的:

from enum import Enum


class colorEnum(Enum):
    red = 1
    yellow = 2
    blue = 3
    gray = 1


print(colorEnum.red)
print(colorEnum.gray)

name重复

定义枚举时,成员名称不允许重复,成员名称相同时就会报错。

from enum import Enum
from types import DynamicClassAttribute


class BaseFunc(Enum):
    name = "dgw"
    age = 25
    sex = '男'

    # 父类Enum中的方法
    @DynamicClassAttribute
    def new_name(self):
        """The name of the Enum member."""
        return self._name_


data1 = list(map(lambda x: x.name, BaseFunc))
print(data1)
data2 = list(map(lambda x: x.new_name, BaseFunc))
print(data2)

unique确保唯一

默认情况下,枚举允许多个枚举成员具有相同的值。如需禁用此行为,可以使用装饰器 @enum.unique

from enum import Enum, unique


@unique
class colorEnum(Enum):
    red = 1
    yellow = 2
    blue = 3
    gray = 1


"""
ValueError: duplicate values found in <enum 'colorEnum'>: gray -> red
"""

自动赋值

enum.auto() 函数可自动为枚举成员分配值:

from enum import Enum, auto


class Color(Enum):
    RED = auto()
    GREEN = auto()
    BLUE = auto()


print(list(Color))  # [<Color.RED: 1>, <Color.GREEN: 2>, <Color.BLUE: 3>]

枚举类型的使用

枚举类的取值

  • 可通过名索引访问
  • 可通过值索引访问
  • 获取枚举成的 name 和 value
  • 枚举类名.变量名 直接获取枚举值
  • 枚举类名(value) 根据枚举value获取枚举值变量,value可以是实际的数字、字符串等
  • 枚举类名(name).value 获取枚举value
from enum import Enum


class colorEnum(Enum):
    red = 1
    yellow = 2
    blue = 3


print(colorEnum.red)  # colorEnum.red
print(type(colorEnum.red))  # <enum 'colorEnum'>
print(colorEnum.red.value)  # 1
print(type(colorEnum.red.value))  # <class 'int'>
print(colorEnum(1))  # colorEnum.red

获枚举取值

枚举变量是name=value的形式

可以使用value取值value或者name

可以使用name变量去取值value或者name

from enum import Enum


class colorEnum(Enum):
    red = 1
    yellow = 2
    blue = 3


print(colorEnum(1))
print(colorEnum(1).value)
print(colorEnum["red"])
print(colorEnum["red"].value)

"""
colorEnum.red
1
colorEnum.red
1
"""

获取枚举的names和values

使用魔法方法__members__获取values和names,结果是dict数组

from enum import Enum


class colorEnum(Enum):
    red = 1
    yellow = 2
    blue = 3


print(colorEnum.__members__.values())
print(colorEnum.__members__.keys())

"""
dict_values([<colorEnum.red: 1>, <colorEnum.yellow: 2>, <colorEnum.blue: 3>])
dict_keys(['red', 'yellow', 'blue'])
"""

举例:

判断变量是否在我们枚举类中,在的话打印出值:

colors=["red","blue","pink"]
for color in colors:
    if color in colorEnum.__members__.keys():
        print(colorEnum[color].value)
        
"""
1
3
"""        

枚举值value:name的映射函数:_value2member_map_

from enum import Enum


class colorEnum(Enum):
    red = 1
    yellow = 2
    blue = 3


print(colorEnum._value2member_map_)

"""
red
yellow
"""

枚举类的遍历

# 方法一:

for name, member in Month.__members__.items():
    print(name, '=>', member, ',', member.value)

# 方法二:
# 枚举支持迭代器,可以遍历枚举成员
for v in Mon:
    print(v)

如果枚举有值重复的成员,循环遍历枚举时只获取值重复成员的第一个成员

from enum import Enum


class BaseFunc(Enum):
    name = "张三"
    names = "张三"
    age = 25
    sex = '男'


for value in BaseFunc:
    print(value, value.name, value.value)

如果想把值重复的成员也遍历出来,要用枚举的一个特殊属性__members__

from enum import Enum


class BaseFunc(Enum):
    name = "张三"
    names = "张三"
    age = 25
    sex = '男'


for value in BaseFunc.__members__.items():
    print(value)

比较大小

枚举成员间不允许比较大小

from enum import Enum


class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3


print(Color.RED < Color.BLUE)  # TypeError: '<' not supported between instances of 'Color' and 'Color'

与非枚举值的比较总不相等:

from enum import Enum


class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 3


print(Color.RED == 1)  # False

混合枚举

from enum import Enum

# 通过多重继承创建支持整数比较的枚举
class Size(int, Enum):
    S = 1
    M = 2
    L = 3
    XL = 4

print(Size.S > Size.M)
# 实现和上述代码一样的功能
from enum import IntEnum


# 通过IntEnum创建支持整数比较的枚举
class Size(IntEnum):
    S = 1
    M = 2
    L = 3
    XL = 4


print(Size.S > Size.M) # False

基于位掩码的枚举类型enum.Flag

from enum import IntFlag, Flag, auto


# 创建基于位掩码的枚举类型,注意成员值为2的幂,最好不要自定义
# 如果想创建整数枚举继承IntFlag即可
class Permissions(Flag):
    READ = auto()  # 定义读权限
    WRITE = auto()  # 定义写权限
    EXECUTE = auto()  # 定义执行权限
    DELETE = auto()  # 定义删除权限


# 使用 name 和 value 属性获取枚举名称和值
# 可以看到各个成员的值是2的幂
for p in Permissions:
    print(p.name, p.value)

# 使用枚举成员
perms_rw = Permissions.READ | Permissions.WRITE  # 用户拥有读和写权限
# 可以看到perms_rw的值为3
print(perms_rw.name, perms_rw.value)

# 检查是否有某个权限
# 使用&运算符来判断一个枚举值中是否包含某个特定的枚举值
if perms_rw & Permissions.READ:  # 如果用户拥有读权限
    print("用户拥有读权限")
if perms_rw & Permissions.WRITE:  # 如果用户拥有写权限
    print("用户拥有写权限")
if perms_rw & Permissions.EXECUTE:  # 如果用户拥有执行权限
    print("用户拥有执行权限")

# 遍历所有权限
for perm in Permissions:
    print(perm)

    
"""
READ 1
WRITE 2
EXECUTE 4
DELETE 8
None 3
用户拥有读权限
用户拥有写权限
Permissions.READ
Permissions.WRITE
Permissions.EXECUTE
Permissions.DELETE
"""
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

士别三日,当挖目相待

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值