zoukankan      html  css  js  c++  java
  • 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 <enum 'Color'>
    print(Color.red, type(Color.red))  # Color.red <enum 'Color'>
    # 打印的是<enum 'Color'>类型
    
    # 那么如何获取里面的值呢?
    # 调用name获取名称,调用value获取值
    print(Color.red.name, type(Color.red.name))  # red <class 'str'>
    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 <enum 'Color'>: 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
    
  • 相关阅读:
    ComboBox.DoubleClick事件
    mktime 夏令时
    STL String的使用[转]
    加在电源后至进入操作系统前的计算机的行为
    C语言数据类型大小分析(基于VC2005编译器)
    linux线程同步之条件变量
    windows 下架设svn服务器(转载+修改) (非利用Google项目托管)
    浅尝《Windows核心编程》之内核对象
    C——数组与指针
    如何用U盘做系统启动盘WINPE 并且 利用WINPE安装Ghost
  • 原文地址:https://www.cnblogs.com/traditional/p/11111339.html
Copyright © 2011-2022 走看看