python:枚举类

python:枚举类

1 前言

python实际开发中,需要定义类型时,一般是使用一组整数或者字符串来表示。如果使用常规的定义方式,非常容易被外部修改,Python3.4后,增加了枚举类的使用,就是为了解决这种场景而设计的。

python枚举适用场景:值有限且固定(不希望被轻易或随意修改)的数据类型。Java也有枚举类的使用,使用关键字enum实现,而python一般是通过提供的Enum类继承实现的(python类支持多继承,java为类单继承)。

2 使用

2.0 初识枚举类

通过enum.Enum()来实现自定义的枚举类:

(‘SPRING’, ‘SUMMER’, ‘AUTUMN’, ‘WINTER’)是定义的多个枚举值:

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)

执行结果:

在这里插入图片描述

2.1 枚举类简单示例:

还可以通过继承Enum枚举类,来实现一个自定义的枚举类:

from enum import Enum


class OrderStatus(Enum):
    NO_PAY = 0
    PAID = 1
    REFUND = 2


class Type(Enum):
    TYPE_ONE = "fruit"
    TYPE_TWO = "animal"
    TYPE_THREE = "drinks"


print(OrderStatus.REFUND)
# OrderStatus.REFUND

print(Type.TYPE_ONE)
# Type.TYPE_ONE

相比于字典,普通类中的变量,枚举类优势如下:

(1)字典,普通类中的变量支持修改,而枚举类,在类外,是不支持修改的。

OrderStatus.REFUND = 3
# error: AttributeError: Cannot reassign members.

在这里插入图片描述

上述报错是因为,我们继承了Enum类,而Enum类的魔法方法def __setattr__(cls, name, value),限制了只要从_member_map_中获取的值,即会抛出异常:

def __setattr__(cls, name, value):
    """
    Block attempts to reassign Enum members.

    A simple assignment to the class namespace only changes one of the
    several possible ways to get an Enum member from the Enum class,
    resulting in an inconsistent Enumeration.
    """
    member_map = cls.__dict__.get('_member_map_', {
   
   })
    if name in member_map:
        raise AttributeError('Cannot reassign members.')
    super().__setattr__(name, value)

(2)python枚举类中不可以存在key相同的枚举项

下面枚举类有相同key:NO_PAY,会直接抛出异常:

class OrderStatus(Enum):
    NO_PAY = 0
    PAID = 1
    REFUND = 2
    NO_PAY = 4
    #  TypeError: Attempted to reuse key: 'NO_PAY'    

由枚举类的魔法方法def __setitem__(self, key, value)控制:

def __setitem__(self, key, value):
    """
    Changes anything not dundered or not a descriptor.

    If an enum member name is used twice, an error is raised; duplicate
    values are not checked for.

    Single underscore (sunder) names are reserved.
    """
    if _is_private(self._cls_name, key):
        import warnings
        warnings.warn(
                "private variables, such as %r, will be normal attributes in 3.10"
                    % (key, ),
                DeprecationWarning,
                stacklevel=2,
                )
    if _is_sunder(key):
        if key not in (
                '_order_', '_create_pseudo_member_',
                '_generate_next_value_', '_missing_', '_ignore_',
                ):
            raise ValueError('_names_ are reserved for future Enum use')
        if key == '_generate_next_value_':
            # check if members already defined as auto()
            if self._auto_called:
                raise TypeError("_generate_next_value_ must be defined before members")
            setattr(self, '_generate_next_value', value)
        elif key == '_ignore_':
            if isinstance(value, str):
                value = value.replace(',',' ').split()
            else:
                value = list(value)
            self._ignore = value
            already = set(value) & set(self._member_names
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值