Python的枚举类型

2019-08-08 10:23:29 浏览数 (1)

产生:
代码语言:javascript复制
数据类型 dict,list,tuple,set 等等有时并不适用
使用:
代码语言:javascript复制
引入模块:form enum import Enum
示例:
代码语言:javascript复制
所有的枚举类型都是Enum类的子类,Py中没有enum这个数据类型
枚举类中定义了多组常量,枚举类名和标识名推荐大写

from enum import Enum
class EMP(Enum):
    YELLOW = 1
    GREEN = 2
    BLACK = 3
    RED = 4
上述常量只要赋值为不同量即可,可以为不同的数字或不同的字符串

print(EMP.BLACK)
注意:
    这里运行会报错:ImportError: cannot import name 'Enum'
    原因是此文件本身叫做enum.py,这与引包操作产生冲突,需要修改文件名
上述正确打印结果为:EMP.BLACK
如果按一般的类,打印结果应该为3,但是枚举类会打印出本身
继承Enum的枚举类的特点和优势:
代码语言:javascript复制
对于其他实现枚举的方式:
    一是直接定义:
        BLACK = 1   
        RED = 2
    二是使用字典:
        {"BLACK":1,"RED":2}
    三是自定义类:
        class MyEnum():
            BLACK = 1
            RED = 2
上述的缺点:
    上述实现方式,对应关系均是可变的,可以发生赋值
    上述均没有防止重复的功能,不同类型对应值可能相同
枚举的要求:
    类型一般不能随意更改
    类型一般不能出现重复
对于枚举类型:
    from enum import Enum
    class EMP(Enum):
        BLACK = 1
        RED = 2
    EMP.BLACK = 3
    尝试修改时报错:AttributeError: Cannot reassign members.

    from enum import Enum
    class EMP1(Enum):
        BLACK = 1
        BLACK = 2
    相同标签对应不同类型时报错:TypeError: Attempted to reuse key: 'BLACK'
综上:
    枚举类型可以保证类型名称的不重复性、并且保护类型不被修改
注意:
代码语言:javascript复制
区别于枚举名称的重复(不允许):
    class EMP1(Enum):
        BLACK = 1
        RED = 1
    上述这种方式是不报错的,因为这表示两个标签对应同一类别,这是允许的,类似别名的概念
    此时print(EMP1.RED)会打印出EMP1.BLACK
    对于这种类型相同的枚举类型,在遍历时只会遍历EMP1.BLACK
    如果想将别名也全部遍历出来,那么使用
        for x in EMP1.__members__.items():
            print(x)
        输出:
            ('BLACK',<EMP1.BLACK: 1>)
            ('RED',<EMP1.RED: 1>)
    或者使用
        for x in EMP1.__members__:
            print(x)
        输出:
            BLACK
            RED
注意区别:
代码语言:javascript复制
枚举类型、枚举名称、枚举值
对于代码:
    from enum import Enum
    class EMP1(Enum):
        BLACK = 1
        RED = 2
通过枚举类型,访问枚举名称和枚举值:
    print( EMP1.BLACK.value )   #输出 1
    print( EMP1.BLACK.name )    #输出 BLACK
    验证:
        print( type(EMP1.BLACK) )       #输出 <enum 'EMP1'> 枚举类型
        print( type(EMP1.BLACK.name) )  #输出 <class 'str'> 枚举名称
通过枚举名称访问枚举类型
    print( EMP1['BLACK'] )      #输出 EMP1.BLACK
    print( type(EMP1['BLACK'] ))#输出 <enum 'EMP1'>   枚举类型
注意:
代码语言:javascript复制
枚举类本身可以被遍历
for x in EMP1:
   print(x)  
输出:
    EMP1.BLACK
    EMP1.RED
上述将EMP1类中的全部枚举类型都打印出来
枚举类型的比较:
代码语言:javascript复制
限定:同一枚举类中的枚举类型
方式:
    两个枚举之间的等值比较,
    两个枚举之间的身份比较,
    不支持大小比较!!!
示例:
    from enum import Enum
    class EMP1(Enum):
        BLACK = 1
        RED = 2

    print( EMP1.BLACK == EMP1.RED )
    #输出 False ,表明两个枚举类型不相等

    print( EMP1.BLACK == 1 )
    #输出 False ,表明枚举类型的比较不是单纯的数值比较

    print( EMP1.BLACK is EMP1.BLACK )
    #输出 True,表明两者身份相同

对于不同枚举类之间的枚举类型
    class EMP2(Enum):
        BLACK = 1
        RED = 2
    print( EMP1.BLACK == EMP2.BLACK )
    #输出 False
注意:
    虽然对应类型相同,但是两者属于不同类,无从比较
枚举转换
代码语言:javascript复制
将数值形式来转换为枚举类型的操作
示例:
    from enum import Enum
    class EMP1(Enum):
        BLACK = 1
        RED = 2

    param = 1
    print( EMP1(param) )

    #输出EMP1.BLACK
枚举类型的总结:
代码语言:javascript复制
对于继承的Enum类,允许类型为字符串类型
    from enum import Enum
    class EMP1(Enum):
        BLACK = '1'
        RED = '2'

如果继承IntEnum,上述代码会报错,因为不允许非Int类型
    from enum import IntEnum
    class EMP1(IntEnum):
        BLACK = '1'
        RED = '2'

引入的unique模块是一个装饰器,其内不允许重复
    from enum import Enum,unique
    @unique
    class EMP1(Enum):
        BLACK = 1
        RED = 1
    #报错:ValueError:duplicate values found in <enum 'EMP1'>: RED -> BLACK
其他:
代码语言:javascript复制
枚举类型是单例模式,不允许实例化

0 人点赞