ZetCode

Python 枚举

最后修改于 2024 年 3 月 15 日

在本文中,我们将展示如何在 Python 中使用枚举。枚举是一种数据类型,在 Python 3.4 中引入。

枚举是一组绑定到唯一常量值的符号名称的集合。枚举可用于创建简单的自定义数据类型,包括季节、星期、游戏中的武器类型、行星、等级或日期等。按照惯例,枚举名称以大写字母开头,并且是单数形式。

enum 模块用于在 Python 中创建枚举。 枚举使用 class 关键字或使用功能 API 创建。

存在特定的派生枚举 enum.IntEnumenum.IntFlagenum.Flag

简单示例

以下是一个简单的 Python 枚举示例。

main.py
#!/usr/bin/python

from enum import Enum


class Season(Enum):
    SPRING = 1
    SUMMER = 2
    AUTUMN = 3
    WINTER = 4


seas = Season.SPRING
print(seas)

if seas == Season.SPRING:
    print("Spring")

print(list(Season))

在此示例中,我们有一个 Season 枚举,它具有四个不同的值:SPRING、SUMMER、AUTUMN 和 WINTER。 要访问成员,我们指定枚举名称,后跟一个点和成员名称。

class Season(Enum):
    SPRING = 1
    SUMMER = 2
    AUTUMN = 3
    WINTER = 4

Season 枚举使用 class 关键字创建。 我们继承自 enum.Enum 基类。 我们显式地将数字设置为枚举值。

seas = Season.SPRING
print(seas)

枚举值被分配给变量,并打印到控制台。

if seas == Season.SPRING:
    print("Spring")

Season.SPRING 在 if 表达式中使用。

print(list(Season))

使用 list 内置函数,我们获取 Season 枚举的所有可能值的列表。

$ python main.py
Season.SPRING
Spring
[<Season.SPRING: 1>, <Season.SUMMER: 2>, <Season.AUTUMN: 3>, <Season.WINTER: 4>]

简单示例 II

下一个示例介绍 Python 枚举的一些其他基本功能。

main.py
#!/usr/bin/python

from enum import Enum


class Season(Enum):
    SPRING = 1
    SUMMER = 2
    AUTUMN = 3
    WINTER = 4


seas = Season.SPRING

print(seas)
print(isinstance(seas, Season))
print(type(seas))
print(repr(seas))

print(Season['SPRING'])
print(Season(1))

同样,我们处理使用 class 创建的 Season 枚举。

print(seas)

在这里,我们打印 Season 成员的可读字符串表示形式。

print(isinstance(seas, Season))

使用 isinstance 方法,我们检查变量是否具有 Season 类型的值。

print(type(seas))

type 函数打印变量的类型。

print(repr(seas))

repr 函数提供有关枚举的更多信息。

print(Season['SPRING'])
print(Season(1))

可以通过项目名称和索引访问枚举的成员。

$ python main.py
Season.SPRING
True
<enum 'Season'>
<Season.SPRING: 1>
Season.SPRING
Season.SPRING

函数式创建

可以使用函数式 API 创建 Python 枚举。

main.py
#!/usr/bin/python

from enum import Enum

Season = Enum('Season', 'SPRING SUMMER AUTUMN WINTER', start=1)

seas = Season.SUMMER
print(seas)

if seas == Season.SUMMER:
    print("Summer")

我们可以使用多种方法通过函数式 API 指定值。 在后面的示例中,我们将使用其他函数式方法。

Season = Enum('Season', 'SPRING SUMMER AUTUMN WINTER', start=1)

这里,值在一个字符串中指定,用空格分隔。 start 提供初始值。

$ python main.py
Season.SUMMER
Summer

枚举迭代

我们可以迭代 Python 枚举。

main.py
#!/usr/bin/python

from enum import Enum


Season = Enum('Season', ['SPRING', 'SUMMER', 'AUTUMN', 'WINTER'], start=5)

for season in Season:
    print(season)

for season in Season:
    print(season.name, season.value)

在此示例中,我们创建一个 Season 枚举,其中值在一系列字符串中设置。

for season in Season:
    print(season)

我们在 for 循环中迭代枚举成员。

for season in Season:
    print(season.name, season.value)

这里我们打印他们的名称和值。

$ python main.py
Season.SPRING
Season.SUMMER
Season.AUTUMN
Season.WINTER
SPRING 5
SUMMER 6
AUTUMN 7
WINTER 8

自动值

可以使用 auto 函数自动设置 Python 枚举值。

main.py
#!/usr/bin/python

from enum import Enum, auto


class Season(Enum):
    SPRING = auto()
    SUMMER = auto()
    AUTUMN = auto()
    WINTER = auto()


for season in Season:
    print(season.value)

我们有一个 Season 枚举,它的成员使用 auto 函数获取一个值。

$ python main.py
1
2
3
4

唯一成员值

可以使用 @unique 装饰器强制 Python 枚举的成员值是唯一的。

main.py
#!/usr/bin/python

from enum import Enum, unique

@unique
class Season(Enum):
    SPRING = 1
    SUMMER = 2
    AUTUMN = 3
    WINTER = 3
    # WINTER = 4


for season in Season:
    print(season)

该示例失败,并出现 ValueError: duplicate values found in <enum 'Season'>: WINTER -> AUTUMN 错误,因为 AUTUMN 和 WINTER 成员具有相同的值。 如果我们注释掉 @unique 装饰器,则该示例将打印三个成员; WINTER 被忽略。

__members__ 属性

特殊属性 __members__ 是一个只读的、将名称映射到成员的有序映射。

main.py
#!/usr/bin/python

from enum import Enum


Season = Enum('Season', [('SPRING', 1), ('SUMMER', 2), 
    ('AUTUMN', 3), ('WINTER', 4)])


for name, member in Season.__members__.items():
    print(name, member)

在此示例中,我们使用 __members__ 属性。 枚举成员是使用函数式 API 通过元组列表创建的。

$ python main.py
SPRING Season.SPRING
SUMMER Season.SUMMER
AUTUMN Season.AUTUMN
WINTER Season.WINTER

enum.Flag

enum.Flag 是一个基类,用于创建可以使用按位运算组合的枚举常量,而不会丢失其 Flag 成员资格。

main.py
#!/usr/bin/python

from enum import Flag, auto


class Perm(Flag):
    EXECUTE = auto()
    WRITE = auto()
    READ = auto()


print(list(Perm))
print(Perm.READ | Perm.WRITE)

该示例显示了如何在权限上使用 Flag

$ python main.py
[<Perm.EXECUTE: 1>, <Perm.WRITE: 2>, <Perm.READ: 4>]
Perm.READ|WRITE

具有静态方法的枚举

以下示例介绍具有自定义静态方法的枚举。

main.py
#!/usr/bin/python

from enum import Enum
import random


class Day(Enum):
    Monday = 0
    Tuesday = 1
    Wednesday = 2
    Thursday = 3
    Friday = 4
    Saturday = 5
    Sunday = 6

    @staticmethod
    def random_day():
        return random.choice(list(Day))


rdays = [Day.random_day() for _ in range(10)]

for e in rdays:
    print(e)

该示例创建一个随机的日期列表。

class Day(Enum):
    Monday = 0
    Tuesday = 1
    Wednesday = 2
    Thursday = 3
    Friday = 4
    Saturday = 5
    Sunday = 6

    @staticmethod
    def random_day():
        return random.choice(list(Day))

我们定义一个 Day 枚举。 random_day 静态方法从枚举的键中返回一个随机选择。

rdays = [Day.random_day() for _ in range(10)]

使用列表推导式,我们创建一个包含十个随机日期的列表。

$ python main.py
Day.Thursday
Day.Wednesday
Day.Monday
Day.Sunday
Day.Saturday
Day.Sunday
Day.Friday
Day.Sunday
Day.Monday
Day.Monday

我们有一个硬币,它有两个枚举值:HEADSTAILS

main.py
from enum import Enum
import random


class Coin(Enum):
    HEADS = 0
    TAILS = 1

    @staticmethod
    def toss():
        return random.choice(list(Coin))


for _ in range(15):
    print(f'{Coin.toss()}', end=' ')

在此示例中,我们掷硬币十五次。

@staticmethod
def toss():
    return random.choice(list(Coin))

静态 toss 方法随机返回其中一个值。

$ python main.py
Coin.TAILS Coin.TAILS Coin.HEADS Coin.HEADS Coin.TAILS Coin.HEADS Coin.TAILS ...

使用模式匹配

match/case 关键字可以与枚举一起使用以创建简洁的代码。

main.py
#!/usr/bin/python

from enum import Enum
import random


class Day(Enum):
    Monday = 0
    Tuesday = 1
    Wednesday = 2
    Thursday = 3
    Friday = 4
    Saturday = 5
    Sunday = 6

days = [Day.Monday, Day.Tuesday, Day.Wednesday,
        Day.Thursday, Day.Friday, Day.Saturday, Day.Sunday]

res = random.sample(days, 4)

for e in res:

    match e:
        case Day.Monday:
            print("monday")
        case Day.Tuesday:
            print("tuesday")
        case Day.Wednesday:
            print("wednesay")
        case Day.Thursday:
            print("thursday")
        case Day.Friday:
            print("friday")
        case Day.Saturday:
            print("saturday")
        case Day.Sunday:
            print("sunday")

在此示例中,我们定义一个 Day 枚举。

days = [Day.Monday, Day.Tuesday, Day.Wednesday,
        Day.Thursday, Day.Friday, Day.Saturday, Day.Sunday]

res = random.sample(days, 4)

我们从列表中随机选择四个日期。

for e in res:

    match e:
        case Day.Monday:
            print("monday")
        case Day.Tuesday:
            print("tuesday")
        case Day.Wednesday:
            print("wednesay")
        case Day.Thursday:
            print("thursday")
        case Day.Friday:
            print("friday")
        case Day.Saturday:
            print("saturday")
        case Day.Sunday:
            print("sunday")

我们检查四个选择的值,并打印其相应的字符串表示形式。 对于每个选项,我们都有一个特定的 case 分支。

$ python main.py
monday
friday
thursday
sunday

来源

Python 枚举 - 语言参考

在本文中,我们使用了 Python 枚举。

作者

我的名字是 Jan Bodnar,我是一位充满热情的程序员,拥有丰富的编程经验。 自 2007 年以来,我一直在撰写编程文章。 迄今为止,我已经撰写了超过 1,400 篇文章和 8 本电子书。 我拥有超过十年的编程教学经验。

列出所有 Python 教程