美文网首页
枚举类的优雅写法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

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

  • Android枚举实现Parcelable接口

    枚举类实现Parcelable的写法如下: 当枚举类为一个类的成员变量,并且该类也要实现Parcelable接口时...

  • 总结复写一下java 单例的各种写法6种

    普通写法(饿汉式) 懒汉式 升级一点的写法 再升级一点的写法 内部类写法 枚举类写法

  • Hello Java

    目录 Java-基础(1/6) Java-对象(2/6) Java-核心库类 上(3/6) Java-核心库类下(...

  • JAVA-枚举

    JAVA-枚举 sschrodinger 2018/11/5 枚举基本形式 枚举的基本形式如上所示,基本可以看出,...

  • 优雅的类写法

    前言 虽然现在已经是ES6的时代,但是,还是有必要了解下ES5是怎么写一个类的。本文详述JavaScript面向对...

  • OC中枚举写法 以及 字符串类型枚举实现探索

    常见枚举写法 C语言模式的枚举写法:enum 普通【整型】枚举写法 :NS_ENUM 位移枚举 :NS_OPTIO...

  • Java-浅析Object类

    Java-浅析Object类 ++2016.7.19++byside @Java-浅析Object类 ======...

  • Python_枚举

    一、枚举 Enum类 Python中所有枚举类型都是enum模块下的Enum类的子类。 枚举中的标识最好全部使用大...

  • [Java]重学Java-枚举类

    枚举可以做什么 假设我们现在想表达星期,为了避免魔法值的出现,我们可能会写一个常量类: 这样一来,1-7的星期数就...

网友评论

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

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