Python中的枚举类enum

python,枚举,enum · 浏览次数 : 269

小编点评

**原文** ```python orders_map = { "first": 0, "second": 1, "third": 2, # ...其他顺序和值 ... } ``` **说明** * `orders_map` 是一个字典,其中每个 key 是一个顺序,每个 value 是一个用例的顺序。 * `order` 是枚举类型 `Enum` 的一个实例。 * `order.value` 返回枚举中该实例的值。 * `order` 可以使用 `__eq__` 和 `__ne__` 方法比较两个枚举实例是否相等。

正文


0. 本文来历

  • 我当时就比较好奇它的顺序和英文的对应关系,肯定是写死的,找了下就发现在源码sorter.py中定义了一个dict如下

     orders_map = {
         "first": 0,
         "second": 1,
         "third": 2,
         "fourth": 3,
         "fifth": 4,
         "sixth": 5,
         "seventh": 6,
         "eighth": 7,
         "last": -1,
         "second_to_last": -2,
         "third_to_last": -3,
         "fourth_to_last": -4,
         "fifth_to_last": -5,
         "sixth_to_last": -6,
         "seventh_to_last": -7,
         "eighth_to_last": -8,
     }
  • 于是乎顺道看了下它其他的源代码,在settings这个模块中有如下一段

     class Scope(Enum):
         CLASS = 1
         MODULE = 2
         SESSION = 3
     
     
     class Settings:
         """Holds all configuration settings."""
         valid_scopes = {
             "class": Scope.CLASS,
             "module": Scope.MODULE,
             "session": Scope.SESSION,
        }
        ...
  • 之前在python中使用枚举更多是用来遍历容器(确切的说列表,虽说它支持多数sequence)

     list1 = [1,3,5,7]
     for i,v in enumerate(list1):
         print(f'第{i+1}个元素是{v}')
         
     # 输出
     第1个元素是1
     第2个元素是3
     第3个元素是5
     第4个元素是7

     

1. 什么是枚举enumeration

枚举模块(enum)是Python 3.4添加的功能,什么是枚举(enumeration)呢?根据官方文档:

An enumeration is a set of symbolic names bound to unique, constant values. Within an enumeration, the values can be compared by identity, and the enumeration itself can be iterated over

即枚举代表了一系列互不相同的常量,这一系列常量可以通过identity互相比较,也可以进行迭代。

 from enum import Enum
 # 比如一个环境的定义
 class Env(Enum):
  UI = 0
  API = 1
  PERFORMANCE = 2
  COMP = 3
 
 

2. 枚举的应用场景

PEP 435中的介绍

The properties of an enumeration are useful for defining an immutable, related set of constant values that may or may not have a semantic meaning.

在Python中,使用枚举的目的主要是方便常量的管理,方便记忆的同时使代码更加简洁易读

举个例子,在代码中通常使用不同的整数代表一些常量。比如用0代表UI,1代表API等。但是带来的麻烦是:写代码/阅读代码的人极有可能不明白这个0背后的意义。用枚举就可以解决这个问题。

而且注意:枚举的value一旦确定,是不可更改的,这样就保证了常量的安全

 

3. 使用

name和value属性

  • 类名.Field.name 访问字段名

  • 类名.Field.value 访问字段值(更常用)

 from enum import Enum
 
 
 # 比如一个环境的定义
 class Env(Enum):
     UI = 0
     API = 1
     PERFORMANCE = 2
     COMP = 3
 
 # 典型的访问 类名.Field.name
 print(Env.COMP.name)   # COMP
 print(Env.COMP.value)  # 3
 

 

不可变

  • 有点常量的感觉,但这点是非常有优势的

 Env.COMP.value = 4
 Traceback (most recent call last):
   File "D:\enum_test.py", line 14, in <module>
     Env.COMP.value = 4
   File "D:\Python39\lib\types.py", line 182, in __set__
     raise AttributeError("can't set attribute")
 AttributeError: can't set attribute

 

不仅仅支持数字

 class Config(Enum):
     HOST = 'https://www.baidu.com'
     DB = '192.168.1.1'
     PORT = 3306
     USERNAME = 'ADMIN'
     PASSWORD = '123456'
 
 
 print(Config.HOST.value)  # https://www.baidu.com

 

unique 装饰器

  • 要对enum的item进行唯一性限制可以用该装饰器

     from enum import Enum,unique
     
     class Env1(Enum):
         MONDAY = 1
         FLAG = 1
     
     print(Env1.FLAG.value)  # 不加装饰器可以重复
     
     @unique
     class Env2(Enum):
         MONDAY = 1
         FLAG = 1
         
     Traceback (most recent call last):
       File "D:\enum_test.py", line 10, in <module>
         class Env2(Enum):
       File "D:\Python39\lib\enum.py", line 1013, in unique
         raise ValueError('duplicate values found in %r: %s' %
     ValueError: duplicate values found in <enum 'Env2'>: FLAG -> MONDAY

     

4. 参考

 

  • enum还有一些其他的功能,比如

    • auto:自动产生一些内容

       >>> from enum import Enum, auto
       >>> class Color(Enum):
       ...     RED = auto()
       ...     BLUE = auto()
       ...     GREEN = auto()
    • IntEnum继承自int和Enum,它只允许枚举的value为整数型

    • Flag和Enum的不同在于:

      • Flag的value只能是整数;

      • Flag支持位运算符(&与、|或、^异或、~取反)

    • IntFlag继承自int和Flag,因此int和Flag的特性它都有,即

      • IntFlag的value只能是整数;

      • IntFlag支持位运算符(&与、|或、^异或、~取反)

      • IntFlag还能当成整数用,比如和整数进行运算,索引等等

    •  

  • 更多信息可以参考官文:https://docs.python.org/3.9/library/enum.html?highlight=enum#module-enum

 

 

与Python中的枚举类enum相似的内容:

Python中的枚举类enum

0. 本文来历 上一篇文章,我写了Pytest插件pytest-order指定用例顺序 我当时就比较好奇它的顺序和英文的对应关系,肯定是写死的,找了下就发现在源码sorter.py中定义了一个dict如下 orders_map = { "first": 0, "second": 1, "third"

一篇文章掌握Python中多种表达式的使用:算术表达式、字符串表达式、列表推导式、字典推导式、_集合推导式、_生成器表达式、逻辑表达式、函数调用表达式

Python 中的表达式可以包含各种元素,如变量、常量、运算符、函数调用等。以下是 Python 表达式的一些分类及其详细例子: 1. 算术表达式 算术表达式涉及基本的数学运算,如加、减、乘、除等。 # 加法表达式 sum = 3 + 5 # 结果为 8 # 乘法表达式 product = 4 *

Python的Lambda函数: 一把极简编程的瑞士军刀

Python中的`lambda`函数,或者叫匿名函数,是一个极其强大的工具。它以简洁、优雅的语法提供了创建函数的快速方式。在本篇文章中,我们将全方位地深入研究lambda函数的用法和特点,通过理论和实例相结合的方式,让你的Python编程技巧更上一层楼。

Python中的弱引用与基础类型支持情况探究

## 背景 最近有一个业务场景需要用Python自行实现一个简单的LRU cache,不可避免的接触到了弱引用这一概念,这里记录一下。 ## 强引用 Python内存回收由垃圾回收器自动管理,当一个对象的引用计数归0时,其内存就可能被回收掉,而引用计数器的数值其实就是代表有多少个强引用指向该对象,我

Python 设置环境变量方法

### Python中的os模块 Python中的os模块提供了很多与操作系统相关的功能。其中就包括设置环境变量的方法,即setenv()方法。 使用os.setenv()方法设置环境变量 ```python import os os.setenv('VAR_NAME', 'VAR_VALUE')

< Python全景系列-5 > 解锁Python并发编程:多线程和多进程的神秘面纱揭晓

深入探讨Python中的并发编程,特别关注多线程和多进程的应用。我们将先从基本概念开始,然后通过详细举例探讨每一种机制,最后分享一些实战经验以及一种优雅的编程技巧。

4.0 Python 变量与作用域

在python中,变量的作用域决定了变量在哪些位置可以被访问。一个程序中的变量并不是所有的地方都可以访问的,其访问权限决定于变量的赋值位置。python中有两种最基本的变量作用域:局部作用域和全局作用域。局部变量是在函数内部定义的变量,只能在其被声明的函数内部访问。而全局变量则是在函数外定义的变量,可以在整个程序的范围内被访问。局部变量只有在其被声明的函数内部才能被访问,全局变量则可以在程序的任何

浅谈Python中的包

浅谈Python中的包 Package的定义(你以为的) 你在很多的地方都能看到关于package的定义:在Python中在当前目录下有__init__.py文件的目录即为一个package。 嗯,包括python目前的官网文档也是类似这么介绍的 https://docs.python.org/zh

2.0 Python 数据结构与类型

数据类型是编程语言中的一个重要概念,它定义了数据的类型和提供了特定的操作和方法。在 python 中,数据类型的作用是将不同类型的数据进行分类和定义,例如数字、字符串、列表、元组、集合、字典等。这些数据类型不仅定义了数据的类型,还为数据提供了一些特定的操作和方法,例如字符串支持连接和分割,列表支持排序和添加元素,字典支持查找和更新等。因此,选择合适的数据类型是 python 编程的重要组成部分。

5.0 Python 定义并使用函数

函数是python程序中的基本模块化单位,它是一段可重用的代码,可以被多次调用执行。函数接受一些输入参数,并且在执行时可能会产生一些输出结果。函数定义了一个功能的封装,使得代码能够模块化和组织结构化,更容易理解和维护。在python中,函数可以返回一个值或者不返回任何值,而且函数的参数可以是任何python对象,包括数字、字符串、列表、元组等。python内置了许多函数,同时也支持用户自定义函数。