专栏首页极客起源Python编程思想(31):枚举类型深度详解

Python编程思想(31):枚举类型深度详解

在很多场景下,一个变量的值是固定且有限的,例如,季节只有4个值(春、夏、秋、冬),性别只有2个值(男和女)。这种值有限且固定的数据类型在Python中称为枚举类型。

1. 枚举类型基础

在Python中有两种方式来定义枚举类型:

  • 直接使用Enum列出多个枚举值来创建枚举类
  • 通过继承Enum基类来派生枚举类

如下面的代码演示了直接使用Enum列出多个枚举值来创建枚举类类型。

示例代码:enum_demo. py

import enum
# 定义Season枚举类
Season = enum.Enum('Season', ('SPRING', 'SUMMER', 'AUTUMN', 'WINTER'))
# 直接访问指定枚举
print(Season.SPRING)
# 访问枚举成员的变量名
print(Season.SPRING.name)
# 访问枚举成员的值
print(Season.SPRING.value)

# 根据枚举变量名访问枚举对象
print(Season['WINTER']) # Season.WINTER
# 根据枚举值访问枚举对象
print(Season(2)) # Season.SUMMER

# 遍历Season枚举的所有成员
for name, member in Season.__members__.items():
    print(name, '=>', member, ',', member.value)

执行这段代码,会输出如下的结果:

Season.SPRING
SPRING
1
Season.WINTER
Season.SUMMER
SPRING => Season.SPRING , 1
SUMMER => Season.SUMMER , 2
AUTUMN => Season.AUTUMN , 3
WINTER => Season.WINTER , 4

在这段代码中,使用了enum.Enum来定义枚举类型。Enum是一个类,创建枚举类型的过程相当于创建Enum类的实例,因为调用的是Enum类的构造方法。该构造方法的第1个参数是枚举类的类名,第2个参数是一个元组,用于列出所有枚举值。在定义了上面的 Season枚举类之后,程序可直接通过枚举值进行访问,这些枚举值都是该枚举的成员,每个成员都有name和value两个属性,其中name属性值为该枚举值的变量名,value代表该枚举值的序号(序号通常从1开始)。

程序除可直接使用枚举之外,还可通过枚举变量名或枚举值来访问指定枚举对象,代码如下:

print(Season['WINTER']) # Season.WINTER

根据枚举值访问枚举对象:

print(Season(2)) # Season.SUMMER

此外,Python还为枚举提供了一个 members属性,该属性返回一个dict字典,字典包含了该枚举的所有枚举实例。程序可通过遍历 members属性来访问枚举的所有实例。

如果要定义更复杂的枚举类型,则可通过继承Enum类来派生枚举类,在这种方式下程序就可以为枚举类型额外定义方法了,

示例代码:ext_enum.py

import enum
class Orientation(enum.Enum):
    # 为序列值指定value值
    EAST = '东'
    SOUTH = '南'
    WEST = '西'
    NORTH = '北'
    def info(self):
        print(f'这是一个代表方向【{self.value}】的枚举')
print(Orientation.EAST)
print(Orientation.EAST.value)
# 通过枚举变量名访问枚举
print(Orientation['NORTH'])
# 通过枚举值来访问枚举
print(Orientation('北'))
# 调用枚举的info()方法
Orientation.EAST.info()
# 遍历Orientation枚举的所有成员
for name, member in Orientation.__members__.items():
    print(name, '=>', member, ',', member.value)

上面程序通过继承Enum派生了 Orientation枚举类,通过这种方式派生的枚举类可以额外定义方法,如上面的 info方法,也可为枚举指定 value(value的值默认是1、2、3、…)。

虽然此时 Orientation枚举类型的 value是str类型,但该枚举类同样可通过 value来访问特定枚举值,如上面程序中的 Orientation(’北'),这是完全允许的。运行上面代码,可以看到如下输出结果:

Orientation.EAST
东
Orientation.NORTH
Orientation.NORTH
这是一个代表方向【东】的枚举
EAST => Orientation.EAST , 东
SOUTH => Orientation.SOUTH , 南
WEST => Orientation.WEST , 西
NORTH => Orientation.NORTH , 北

2. 枚举类的构造方法

枚举也是类,因此枚举也可以定义构造方法。为枚举定义构造方法之后,在定义枚举实例时必须为构造方法参数设置值,代码如下:

示例代码:enum_constructor,py

import enum
class Sex(enum.Enum):
    MALE = '男', '纯爷们'
    FEMALE = '女', '纯姐们'
    def __init__(self, cn_name, desc):
        self._cn_name = cn_name
        self._desc = desc
    @property
    def desc(self):
        return self._desc
    @property
    def cn_name(self):
        return self._cn_name
# 访问FEMALE的name
print('FEMALE的name:', Sex.FEMALE.name)
# 访问FEMALE的value
print('FEMALE的value:', Sex.FEMALE.value)
# 访问自定义的cn_name属性
print('FEMALE的cn_name:', Sex.FEMALE.cn_name)
# 访问自定义的desc属性
print('FEMALE的desc:', Sex.FEMALE.desc)

上面程序定义了Sex枚举类,并为它定义了一个构造方法,调用该构造方法需要传入 cn_name和desc两个参数,因此程序使用如下代码来定义 Sex的枚举值。

MALE = '男', '纯爷们'
FEMALE = '女', '纯姐们'

上面代码为MALE枚举指定的 value是"男"和"纯爷们"这两个字符串,其实它们会被自动封装成元组后传给MALE的vaue属性;而且此处传入的"男"和"纯爷们"这两个参数值正好分别传给cn name和desc两个参数。简单来说,枚举的构造方法需要几个参数,此处就必须指定几个值。

运行这段代码,会输出如下内容:

FEMALE的name: FEMALE
FEMALE的value: ('女', '纯姐们')
FEMALE的cn_name: 女
FEMALE的desc: 纯姐们

本文分享自微信公众号 - 极客起源(geekculture),作者:geekori

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2020-07-03

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 你所不知道的Python迭代器

    迭代就是循环的意思,也就是对一个集合中的元素进行循环,从而得到每一个元素。对于我们自定义的类,也可以让其支持迭代,这就是本文要介绍的特殊成员方法__iter__...

    蒙娜丽宁
  • 冠状病毒传播仿真器(Python版本)【附源代码】

    本文首先会解释一下到底什么是"冠状病毒",以及杀死"冠状病毒"的方法。然后会利用Python实现一个"冠状病毒"传播仿真器,来演示一下为何“不出门“ +“疯狂建...

    蒙娜丽宁
  • Python编程思想(4):字符串类型

    字符串的意思就是“一串字符”,也可以看做是字符的序列。比如“Helo, Mike”是一个字符串,“How are you?”也是一个字符串。Python要求字符...

    蒙娜丽宁
  • Java基础15:深入剖析Java枚举类

    本文介绍了枚举类的基本概念,使用方法,以及底层实现原理。帮助你更好地使用枚举类并且理解枚举类的内部实现细节。

    黄小斜
  • 窥探Swift之别样的枚举类型

      想必写过程序的童鞋对枚举类型并不陌生吧,使用枚举类型的好处是多多的,在这儿就不做过多的赘述了。Fundation框架和UIKit中的枚举更是数不胜数,枚举可...

    lizelu
  • 一起学Rust-枚举

    枚举的定义在其他许多的语言中都有实现,举例来说,比如C中的枚举,枚举值在未赋值的情况下默认从0开始递增或从上一个枚举值开始递增,值类型可以是整数或字符类型,实质...

    MikeLoveRust
  • Java高级特性之枚举学习总结

    在Java SE5之前,我们要使用枚举类型时,通常会使用static final 定义一组int常量来标识,代码如下

    哲洛不闹
  • 一起学Rust-枚举

    枚举的定义在其他许多的语言中都有实现,举例来说,比如C中的枚举,枚举值在未赋值的情况下默认从0开始递增或从上一个枚举值开始递增,值类型可以是整数或字符类型,实质...

    江湖安得便相忘
  • C# Enum设计和使用的相关技巧

    C#的Enum设计的相关指导在网上有相关文章论述: 英文:Design Guidelines Update: Enum Design 中文:C# Idioms:...

    张善友
  • 夯实Java基础系列14:深入理解Java枚举类

    枚举(enum)类型是Java 5新增的特性,它是一种新的类型,允许用常量来表示特定的数据片断,而且全部都以类型安全的形式来表示。

    Java技术江湖

扫码关注云+社区

领取腾讯云代金券