美文网首页
枚举类的优雅写法Java->Python

枚举类的优雅写法Java->Python

作者: 我只要喝点果粒橙 | 来源:发表于2020-12-05 17:26 被阅读0次

    枚举类型作为与接口、类同一级别的存在,自然有它独特的用途。至于它性能上的优势暂且不谈,我们在这篇文章中只是考虑怎么把Enum写得更优雅

    Java

    Enum的写法

    在阿里实习的时候印象最深的就是学到了枚举的写法, 大致如下所示

    public enum EnumOperationPermission implements IEnumBehaviour {
        // ----------------------- 实际的枚举对象 ------------------------
        SAVE("保存", 0), 
        SUBMIT("提交", 1), 
        BACK("退回", 2), 
        VIEWCOMMENTS("查看意见", 3), 
        SIGN("签发", 4), 
        DISTRIBUTE("分发", 5), 
        CALLBACK("撤回", 6), 
        NODE("节点", 7), 
        BROWSINFO("浏览情况", 8), 
        FINISH("完成", 9),
        DETAIL("订票明细",10);
        // ----------------------- 实际的枚举对象 ------------------------
       private String mName;
       private int mId;
    
       private EnumOperationPermission(String name, int id) {
         this.mName = name;
         this.mId = id;
       }
        
       // 一般只有get, 没有set
       public String getName() {
         return mName;
       }
       public int getId() {
         return mId;
       }
        
       // 下面的用途为自定义跟enum的valueOf相同, 即通过某个值返回enum这个类
       public static EnumOperationPermission parse(String name) { 
         EnumOperationPermission[] enumList = EnumOperationPermission.values();
         for (IEnumBehaviour enumInstance : enumList) {
           if (enumInstance.toString().equalsIgnoreCase(name) || enumInstance.getName().equalsIgnoreCase(name)
               || String.valueOf(enumInstance.getId()).equalsIgnoreCase(name)) {
             return (EnumOperationPermission) enumInstance;
           }
         }
         return EnumOperationPermission.SAVE;
       }
     }
    

    Python

    最简易的写法

    from enum import Enum
    class Color(Enum):
        RED = 1
        YELLOW = 2
        BLUE = 3
    

    枚举类的特点:

    • 标签值不可被修改

    • 一个标签只能对应一个值,但多个标签可以对应相同的值(别名) --> 不同key可以有相同的val( 如果不允许存在相同val, 则在类前加上装饰器@unique, 需要从enum包中导入)

    • 枚举类型可以做等值比较和身份比较,但是不能做大小比较

      from enum import Enum
      class Color(Enum):
          RED = 1
          YELLOW = 1
          BLUE = 3
      
      print(Color.RED == Color.YELLOW)
       True
      print(Color.RED is Color.YELLOW)
       True
      

    枚举类型、枚举名称、枚举值

    跟Java不同的是,Java一般自己定义有哪些属性,如name, code。 而Python中有设好的name和value属性

    class Enum(metaclass=EnumMeta):
      @DynamicClassAttribute
        def name(self):
            """The name of the Enum member."""
            return self._name_
    
        @DynamicClassAttribute
        def value(self):
            """The value of the Enum member."""
            return self._value_
    
    • 枚举类型就是指这个枚举类;
    • 枚举实例就是指枚举类型下的具体实例
    • 枚举名称为枚举类型实例的key,本质是Enum.name
    • 枚举名称为枚举类型实例的value,本质Enum.value

    如何使用枚举类型

    可以用读取字典的方式来读取,并且可以遍历:

    from enum import Enum
    class Color(Enum):
        RED = 1
        YELLOW = 1
        BLUE = 3
    
    print(Color['RED'])  访问
    for e in Color:      遍历
        print(e)
     当多个标签对应相同值时,第一个定义的为主名,其他的为别名
     直接遍历无法输出别名,可以用__members__来全部输出
    for e in Color.__members__:
        print(e)
    

    注意Python中是没有类似Java中EnumOperationPermission.values();来获得枚举的所有实例对象的

    如何从python enum类获取所有值?

    如何像Java中一样EnumOperationPermission.values();呢?https://oomake.com/question/8760202中提到Enum有一个members字典,经翻阅源码后发现3.6中并没有这个字典,有的是__member__属性,其返回值为OrderedDict

    class EnumMeta(type):
        def __new__(metacls, cls, bases, classdict):
             ...
            enum_class._member_names_ = []                names in definition order
            enum_class._member_map_ = OrderedDict()       name->value map
        
        @property
        def __members__(cls):
            """Returns a mapping of member name->value.
    
            This mapping lists all enum members, including aliases. Note that this
            is a read-only view of the internal mapping.
    
            """
            return MappingProxyType(cls._member_map_)
    
    

    所有写法有:

    通过类的value属性来获得所有值
    from enum import Enum
    class Color(Enum):
        RED = 1
        GREEN = 'GREEN'
        BLUE = ('blue', '#0000ff')
        
        @staticmethod
        def list():
            '''
            获得所有值
            '''
            return list(map(lambda c: c.value, Color))
    print(Color.list())
    
    模仿Java写法
    
    class Chess(Enum):
        BLACK = {'graph': 'X', 'val': 0}
        WHITE = {'graph': 'O', 'val': 1}
    
        def getChess(color):
            for c in Chess:
                if color == c.value.get("graph"):
                    return c
    
        def getVal(self):
            return self.value.get('val')
    
            
        def getGraph(self):
            return self.value.get('graph')
    
    

    相关文章

      网友评论

          本文标题:枚举类的优雅写法Java->Python

          本文链接:https://www.haomeiwen.com/subject/afbgwktx.html