Mrli
别装作很努力,
因为结局不会陪你演戏。
Contacts:
QQ博客园

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

2022/04/27 计算机基础知识
Word count: 1,017 | Reading time: 5min

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

Java

Enum的写法

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
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

最简易的写法

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

枚举类的特点:

  • 标签值不可被修改

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

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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    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属性

1
2
3
4
5
6
7
8
9
10
11
> 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

如何使用枚举类型

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

1
2
3
4
5
6
7
8
9
10
11
12
13
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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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属性来获得所有值
1
2
3
4
5
6
7
8
9
10
11
12
13
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写法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

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')

Author: Mrli

Link: https://nymrli.top/2020/12/05/枚举类的优雅写法Java-Python/

Copyright: All articles in this blog are licensed under CC BY-NC-SA 3.0 unless stating additionally.

< PreviousPost
浙大2020春夏-人工智能习题3——图像恢复
NextPost >
理解科学计算(numpy,pytorch)中的dim参数
CATALOG
  1. 1. Java
    1. 1.1. Enum的写法
  2. 2. Python
    1. 2.1. 枚举类型、枚举名称、枚举值
    2. 2.2. 如何使用枚举类型
      1. 2.2.1. 如何从python enum类获取所有值?
        1. 2.2.1.1. 通过类的value属性来获得所有值
        2. 2.2.1.2. 模仿Java写法