【python】枚举的基本使用,及如何实现枚举属性的自增长

news/2024/5/18 23:19:28 标签: python, 枚举, 枚举自增

▒ 目录 ▒

    • 🛫 问题
      • 描述
      • 环境
    • 1️⃣ 枚举的基本使用
    • 2️⃣ 实现枚举属性的自增长
    • 🛬 结论
    • 📖 参考资料

🛫 问题

描述

学过c的都知道,c中有enum,可以定义一组特定值的常量。
python也拥有类似的能力,不过,它不是语法层次的,而是以类库的形式提供给开发者。
今天我们就来说说python中的枚举,并通过它实现枚举属性的自增长

环境

版本号描述
文章日期2023-06-29
操作系统Win11 - 21H2 - 22000.1335
Python3.7.1
Python3.5.2

1️⃣ 枚举的基本使用

自定义枚举成员的值

在Python中,使用enum模块来创建枚举类型。枚举类型定义了一组具有命名值的常量。
可以使用枚举类型来避免硬编码常量,并提高代码的可读性和可维护性。

以下是使用enum模块创建枚举类型的示例:

python">from enum import Enum

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

print(Color.RED)    # Color.RED
print(Color.RED.name)   # RED
print(Color.RED.value)  # 1

在上面的示例中,定义了一个名为Color枚举类型,它有三个常量:REDGREENBLUE。每个常量都有一个名称和一个。可以使用常量的名称和值来访问它们。

枚举类型的名称必须是唯一的,但值可以重复。可以使用枚举类型的name属性获取常量的名称,使用value属性获取常量的值。

python">from enum import Enum

class Color(Enum):
    RED = 1
    GREEN = 2
    BLUE = 5
    NEXT = 5
    END = BLUE


print(Color.RED)    # Color.RED
print(Color.RED.name)   # RED
print(Color.NEXT.value)  # 5
print(Color.END.value)  # 5

枚举值唯一:@unique

可以使用@unique装饰器来防止枚举成员具有相同的值。

python">from enum import Enum, unique

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

    @property
    def name(self):
        return self.name.lower()

    @classmethod
    def from_name(cls, name):
        return cls[name.upper()]
 

当定义相同的值NEXT = 5时,会报错。
在这里插入图片描述

枚举成员的别名:@property

可以通过自定义属性,将枚举成员的名称转换为大写或小写。

python">from enum import Enum

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

    @property
    def nameX(self):
        return self.name.lower()


print(Color.RED)    # Color.RED
print(Color.RED.name)    # RED
print(Color.RED.nameX)    # red

枚举成员的元数据

python">from enum import Enum

class Color(Enum):
    RED = ('Red Color', True)
    GREEN = ('Green Color', False)
    BLUE = ('Blue Color', True)

    def __init__(self, description, flag):
        self._description_ = description
        self._flag_ = flag

    @property
    def description(self):
        return self._description_

    @property
    def flag(self):
        return self._flag_

print(Color.GREEN.name)						# GREEN
print(Color.GREEN.value)					# ('Green Color', False)
print(Color.GREEN.description)				# Green Color
print(Color.GREEN.flag)						# False
 

2️⃣ 实现枚举属性的自增长

开发中,经常定义庞大的枚举类型,这时候我们一个个去调整枚举的数值,会非常的麻烦,接下来就通过特殊手段实现枚举类型的值自增长。

python36font_144">python3.6+

python3.7中,我们可以通过auto这个class,自动的实现Ordinal的类属性自动增加,从而完成想要的功能。

python">from enum import IntEnum, Enum, auto

class Color(IntEnum):
    NORTH = 3
    SOUTH = auto()
    EAST = auto()
    WEST = auto()

print(Color.NORTH.value)  # 3
print(Color.SOUTH.value)  # 4
print(Color.EAST.value)   # 5
print(Color.WEST.value)   # 6

python352font_162">python3.5.2

python环境从3.7切换到3.5.2,我们会发现下面报错内容:
在这里插入图片描述

从图中可以看出,python3.5.2中并没有实现auto类,难道python3.5.2不能实现自增长吗?只能使用最原始的,给每个值手动赋值的方式吗?
为了一探究竟,小编翻了翻python文档,文档中给了两种方案:

方案一: 使用Enum类的构造函数

文档中的用法如下:
image.png

示例代码:

python">from enum import Enum

Animal = Enum('Animal', 'ant bee cat dog', start=4)
print(Animal.ant)            # Animal.ant
print(Animal.cat.value)      # 6

方案二: 使用Enum类的构造函数
下面是python文档给的例子,实现自增长的枚举,这也可能就是后期python版本中的实现了。

python">class AutoNumber(Enum):
    def __new__(cls):
        value = len(cls.__members__) + 1
        obj = object.__new__(cls)
        obj._value_ = value
        return obj

class Color(AutoNumber):
    red = ()
    green = ()
    blue = ()

print(Color.green.value) # 2

不过这个代码功能实在有限,red = ()不能改为red = 3,也就是说,不能指定初始值。
所以在python3.5中,直接使用方案一,就可以了。

python2enumfont_208">python2不支持enum模块

这个没啥说的,就是不支持这个库,直接报错。
在这里插入图片描述

没有python2的用户,可以直接通过在线工具尝试该功能:https://c.runoob.com/compile/6/。
在这里插入图片描述

🛬 结论

查了些资料,说auto()这种用法是python3.6的新特性,闹心了,看来不使用新版本的python,很多功能就无法使用。对于无法更新版本的公司(线上稳定版本是旧的python版本,最新版本python无法稳定运行的情况),只能自己想办法实现类似的功能了。

📖 参考资料

  • 在线编译环境 https://c.runoob.com/compile/9/

http://www.niftyadmin.cn/n/698588.html

相关文章

代码随想录二刷day36 | 贪心重叠区间之 435. 无重叠区间 763.划分字母区间 56. 合并区间

day36 435. 无重叠区间763.划分字母区间56. 合并区间 435. 无重叠区间 题目链接 解题思路: 按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了。 此时问题就是要求非交叉区间的最大个数。 这里…

JavaWeb 笔记-1

JavaWeb 笔记-1 初始JavaWeb什么是JavaWeb 一、JDBC1.1、JDBC简介1.2、API详解-DriverManager1.3、API详解-Connection1.4、API详解-Statement1.5、API详解-ResultSet1.6、API详解-PreparedStatement1.6.1、API详解-PreparedStatement-SQL注入演示1.6.2、API详解-PreparedState…

Linux历史及环境搭建(VMware搭建CentOS7环境)

Linux历史及环境搭建 1.Linux历史1.1 UNIX发展的历史1.2 Linux发展历史1.2.1 开源1.2.2 官网1.2.3 发行版本 2.VMware配置CentOS7环境2.1 CentOS下载2.2 配置环境2.3 切换国内阿里源2.4 无图形化界面开机 结语 1.Linux历史 在这里简要介绍Linux的发展史。要说 Linux&#xff0…

Java 引用传递

引用传递是 Java 中一个重要的概念,它与值传递不同,可以使得函数或方法可以修改传入的对象。本文将介绍 Java 中的引用传递,包括其定义、实现方式、与值传递的区别以及示例代码。 什么是引用传递 在 Java 中,变量可以存储基本类…

【GPT】如何拥有离线版本的GPT以及部署过程中的问题

【背景】 目前很多公司由于数据安全的问题,不能使用OpenAI的GPT,同时也没有必要非得使用如此泛用化的GPT。很多公司因此有训练自己的离线GPT的需求,这样的GPT只需要具备专业知识即可。 要使这个成为可能,首先就需要能够让GPT的Mo…

【广州华锐互动】机械设备事故VR模拟体验系统

随着虚拟现实技术的不断发展,越来越多的行业开始尝试将VR技术应用到实际场景中,以提供更加真实的体验。其中,机械伤害事故VR警示教育系统的出现,为机械工程师、安全培训人员等行业提供了一种全新的培训方式。在实现上,…

HFUT Data Structure Experiment: SkipList

写给我的学弟 如果你看到了这个题,赶快跑,千万别选。 这个题的图形化会让你非常痛苦。并且这道题只有小小85分,为啥不换个85分的更简单的?或者换个90分以上的题不好吗。 如果你单单想学习一下这个数据结构,那挺好的&…

CentOS ping命令:name or service not known

1.虚拟机网络连接设置为“NAT模式”,且NAT设置 导航栏“编辑”->“虚拟网络编辑器” ->NAT模式->NAT设置 2.网络配置文件 vi /etc/sysconfig/network-scripts/ifcfg-ens33注:IPADDR和NAT设置里面的IP最后一位要不同 3.DNS设置 vi /etc/reso…