今天偶然看到枚举的一种写法,我测试后感觉有些奇怪
import enum
class TestEnum( str,enum.Enum):
A = "a"
这里同时继承了 str 和 Enum , 我测试了一下语句,
repr(TestEnum.A)
>>> "<TestEnum.A: 'a'>"
str(TestEnum.A)
>>> TestEnum.A'
TestEnum.A == 'a'
>>> True
这里的 TestEnum.A == 'a' 结果为 True , 是怎么判断的?
如果 TestEnum 是 dataclass 类的变量,在 json dumps 时也会自动转换,这是怎么做到的?
from dataclasses import dataclass, asdict
import json
@dataclass
class A:
a: TestEnum=None
test_a = A(TestEnum.A)
asdict(test_a)
>>> {'a': <TestEnum.A: 'a'>}
json.dumps(asdict(test_a))
>>> {"a": "a"}
python 版本 3.9.16
1
cosmain 2023-04-27 16:39:07 +08:00
多继承,继承了 str 的一些成员函数 == 应该是调用了成员方法。
不过这个还真是一个不错的方法。==也好,json 也好 |
2
westoy 2023-04-27 16:39:45 +08:00
因为 Enum 的实现里,Enum 的 members 本身就是这个 Enum 类的实例.......
而你 TestEnum 这个又是继承的 str 导致 TestEnum.A 也变成了 str...... |
3
arischow 2023-04-27 16:51:27 +08:00
|
4
zyx199199 2023-04-27 16:54:34 +08:00
Python 3.10 标准库里自带的 IntEnum 就是同时继承了 int 和 enum 实现的
|
5
Ricardoo OP @westoy 我好像突然有点明白了,又不完全明白。为什么 str(TestEnum.A) 不是'a' ?, 为什么不是优先调用 str 类的__str__方法呢?
|
6
NoOneNoBody 2023-04-27 16:59:09 +08:00
对于最后的问题,查看手册关于 json.JSONEncoder.default() 的说明
就是 json 是如何处理 object 类型的(dict 是 object 类型) |
7
NoOneNoBody 2023-04-27 17:02:41 +08:00
|
8
XYxe 2023-04-27 17:10:15 +08:00
@Ricardoo #5 因为 Enum 有 metaclass EnumType, 在 EnumType 里面对几个函数有特殊处理
TestEnum.__dict__ 可以看到添加的几个的函数 |
9
westoy 2023-04-27 17:13:42 +08:00 1
@Ricardoo
>>> TestEnum.__mro__ (<enum 'TestEnum'>, <class 'str'>, <enum 'Enum'>, <class 'object'>) 从左到右, 没定义就找下一个, 你的 TestEnum 里没定义__str__ 可以追加一个 TestEnum.__str__ = lambda _: str(random.random()) a = str(TestEnum.A) b = str(TestEnum.A) print(a, b, a == b) 再试一下结果看看 |
10
Ricardoo OP @westoy 按照 (<enum 'TestEnum'>, <class 'str'>, <enum 'Enum'>, <class 'object'>) 的顺序。TestEnum 没有 str 定义,但是<class 'str'> 里有__str__ 定义啊,为什么 str(TestEnum.A) 的结果是 TestEnum.A 呢? 我看了下,这是<enum 'Enum'>里__str__的定义,
def __str__(self): return "%s.%s" % (self.__class__.__name__, self._name_) 所以 str(TestEnum.A) , 为什么跳过<class 'str'>, 出的是<enum 'Enum'>里__str__结果呢 |
11
XYxe 2023-04-27 17:36:03 +08:00 1
因为在 enum.EnumType 里面,给 TestEnum 增加了 __str__ 方法,你可以在 TestEnum.__dict__ 里面看到这个方法
|
12
lambdaq 2023-04-27 17:57:17 +08:00
学习。。原来写了那么多的 xxxenum.yyy.value == 'yyy' 都白写了。。
|
14
noparking188 2023-04-28 01:10:10 +08:00
@lambdaq #12 我也是,觉得这样调用麻烦然后直接不继承 Enum 类了,学到了,这就去改代码
|