首页 > 编程语言 >Python中的枚举类enum

Python中的枚举类enum

时间:2022-10-19 10:46:19浏览次数:64  
标签:enum last Python Enum value 枚举 class


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

 

 

标签:enum,last,Python,Enum,value,枚举,class
From: https://www.cnblogs.com/wuxianfeng023/p/16805390.html

相关文章

  • 驱动开发:内核枚举Minifilter微过滤驱动
    Minifilter是一种文件过滤驱动,该驱动简称为微过滤驱动,相对于传统的sfilter文件过滤驱动来说,微过滤驱动编写时更简单,其不需要考虑底层RIP如何派发且无需要考虑兼容性问题,微......
  • Python教程Day03-Python输出、输入、转换数据类型、运算符
    一、输出作用:程序输出内容给用户print('helloPython')age=18print(age)#需求:输出“今年我的年龄是18岁”1、格式化输出格式化输出即按照一定的格式输出内容1.1格......
  • Python list 中删除元素的方法
    在python列表中删除元素主要分为以下3种场景:根据目标元素所在的索引位置进行删除,可以使用del关键字或pop()方法;根据元素本身的值进行删除,可使用列表(list类型)提供的remove(......
  • python 脚本实现bugly自动上传符号文件
    bugly更新之后,符号文件不再支持拖拽或者选择文件的方式上传了,官方提供了一个上传的工具包,通过buglyqq-upload-symbol.jar实现上传,每次上架app都需要手动去配置相关参数和组......
  • python当中map,reduce和filter函数用法和区别
    在python当中,关于map,reduce和filter函数用法。map:对任何可迭代序列中的每一个元素应用对应的函数。python3中返回的是迭代器。reduce:将序列中所有的元素进行合并运算......
  • python封装
    这种变形的特点:1,在类外部无法直接obj.__AttrName2,在类内部可以直接使用:obj.__AttrName3,子类无法覆盖父类__开头的属性0,classA:'类的封装啊'__x=1......
  • python类中的数据问题
    问题:1.)上面的__init__函数中,加*句我不写,为啥不可以?不理解里面怎么传递。。。初始化的时候不是先在内部调用了__init__,生成了L了吗?下面函数不能用这里的L,甚至是a,b这些变......
  • Selenium+Python系列 - 开发环境搭建
    一、写在前面我从未想过自己会写python系列的自动化文章,有些同学会问,那你现在为什么又开始写了?不止一个人找过我,问我可以写一些Python自动化的文章吗,答案是肯定的。笔......
  • Python 操作Excel-openpyxl模块使用
    openpyxl的用法实例1.1Openpyxl库的安装使用openpyxl模块是一个读写Excel2010文档的Python库,如果要处理更早格式的Excel文档,需要用到额外的库,openpyxl是一......
  • 学习python-Day76
    今日学习内容一、虚拟机关键配置名词解释1.虚拟网络编辑器说明桥接模式​ 配置的地址信息和物理主机地址信息相同,容易造成地址冲突NAT模式​ 配置的地址信息和物......