enum:python实现枚举也很优雅

介绍

enum是一个用来枚举的模块

创建枚举类型

import enum


# 创建一个类,继承自enum下的Enum
class Color(enum.Enum):
    red = 1
    green = 2
    blue = 3
    yellow = 4
    pink = 5
    cyan = 6


# 下面便可以通过名称直接获取成员
print(Color["red"], type(Color["red"]))  # Color.red 
print(Color.red, type(Color.red))  # Color.red 
# 打印的是类型

# 那么如何获取里面的值呢?
# 调用name获取名称,调用value获取值
print(Color.red.name, type(Color.red.name))  # red 
print(Color.red.value)  # 1

# 也可以通过迭代来获取值
for c in Color:
    print(c.name, c.value)
"""
red 1
green 2
blue 3
yellow 4
pink 5
cyan 6
"""

名称或者值相同

import enum


# 如果我定义了重复的key(仮)
try:
    class Color(enum.Enum):
        red = 1
        green = 2
        blue = 3
        yellow = 4
        pink = 5
        cyan = 6

        cyan = 5

except Exception as e:
    print(e)  # Attempted to reuse key: 'cyan'

# 提示我们key重复了
import enum


# 如果我定义了重复的value(仮)
class Color(enum.Enum):
    red = 1
    green = 2
    blue = 3
    yellow = 4
    pink = 5
    cyan = 6

    purple = 6


# 这是通过value来获取成员
# 获取成员可以通过Color.key | Color[key]的方式,还可以使用Color(value)的方式
print(Color(6).name)  # cyan
print(Color.purple.name)  # cyan
# 可以看到只打印了cyan
# 如果值相同的话,那么后者相当于前者的别名,两者指向的内容是一样的

for c in Color:
    print(c)
"""
Color.red
Color.green
Color.blue
Color.yellow
Color.pink
Color.cyan
"""
# purple依旧没有打印


# 那如果我就想把值相同的也打印出来,要怎么做呢?
# 枚举内部有一个__members__属性,相当于一个字典
for c in Color.__members__.items():
    print(c[0], c[1])
"""
red Color.red
green Color.green
blue Color.blue
yellow Color.yellow
pink Color.pink
cyan Color.cyan
purple Color.cyan
"""
# 第一个元素是key,str类型。第二个元素是枚举类型。
# 可以看到最后一个,即便key是purple,但是对应的枚举类型依旧是Color.cyan
for c in Color.__members__.items():
    print(c[0], c[1], c[1].name, c[1].value)
"""
red Color.red red 1
green Color.green green 2
blue Color.blue blue 3
yellow Color.yellow yellow 4
pink Color.pink pink 5
cyan Color.cyan cyan 6
purple Color.cyan cyan 6
"""
# 最后一个打印的仍是cyan


# 成员之前也可以进行比较,但只支持is和==操作符,不支持大小比较
print(Color.green is Color.red)  # False
print(Color.green is Color.green)  # True
print(Color.cyan is Color.purple)  # True
print(Color.cyan == Color.purple)  # True

成员的值是否可变

import enum


class Color(enum.Enum):
    red = 1
    green = 2
    blue = 3
    yellow = 4
    pink = 5
    cyan = 6

    purple = 6


try:
    Color.red.name = "xxx"
except Exception as e:
    print(e)  # can't set attribute


try:
    Color.red.value = "xxx"
except Exception as e:
    print(e)  # can't set attribute

# 可以看到是无法赋值的
import enum


class Color(enum.Enum):
    red = 1
    green = 2
    blue = 3
    yellow = 4
    pink = 5
    cyan = []

    purple = []


print(Color.cyan is Color.purple)  # True
Color.cyan.value.append(123)
print(Color.cyan is Color.purple)  # True
"""
可以看到,尽管无法重新赋值,但是本地修改还是可以的,如果是可变类型的话
但是两个还是一样的,因为purple是cyan的别名,当在创建这个类的时候,由于都是空列表,所以认为两者是一样
因此当我对cyan.value进行append的时候,会影响purple
"""

print(Color.cyan.value)  # [123]
print(Color.purple.value)  # [123]

Color.purple.value.append(456)

# 通过反过来也是一样的
print(Color.cyan.value)  # [123, 456]
print(Color.purple.value)  # [123, 456]

强制让成员的值不一样

枚举类,key重复是不允许的,但是值重复是可以的,可如果我也不允许值重复呢?只需要加上一个装饰器即可

import enum


try:
    @enum.unique
    class Color(enum.Enum):
        red = 1
        green = 2
        blue = 3
        yellow = 4
        pink = 5
        cyan = []

        purple = []

except Exception as e:
    print(e)  # duplicate values found in : purple -> cyan
    
# 提示我们purple和cyan的value重复了

比较成员的值

之前说过,枚举成员是不支持大小比较的,但如果我想支持呢?

import enum


# 换一种继承的类,改成IntEnum
class Color(enum.IntEnum):
    red = 1
    green = 2
    blue = 3
    yellow = 4
    pink = 5
    cyan = "6"


# 此时里面的成员要是int类型,或者能将字符串转成int

print(Color.red < Color.blue)  # True
print(Color.red + Color.cyan)  # 7

转载于:https://www.cnblogs.com/traditional/p/11111339.html

你可能感兴趣的:(enum:python实现枚举也很优雅)