zoukankan      html  css  js  c++  java
  • enum:python实现枚举也很优雅

    介绍

     
    enum是一个用来枚举的模块

    创建枚举类型

    python
    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
    """

    名称或者值相同

    python
    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重复了
    python
    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

    成员的值是否可变

    python
    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
    
    # 可以看到是无法赋值的
    
    python
    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重复是不允许的,但是值重复是可以的,可如果我也不允许值重复呢?只需要加上一个装饰器即可

    python
    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重复了

    比较成员的值

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

    python
    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
  • 相关阅读:
    Android开发 ViewConfiguration View的配置信息类
    Android 开发 倒计时功能 转载
    Android 开发 关于7.0 FileUriExposedException异常 详解
    Android 开发 实现文本搜索功能
    Android 开发 Activity里获取View的宽度和高度 转载
    Android 开发 存储目录的详解
    Android 开发 Fresco框架点击小图显示全屏大图实现 ZoomableDraweeView
    Android 开发 将window变暗
    Android 开发 DisplayMetrics获取Android设备的屏幕高宽与其他信息
    Android 开发 DP、PX、SP转换详解
  • 原文地址:https://www.cnblogs.com/valorchang/p/11395476.html
Copyright © 2011-2022 走看看