
今天偶然看到枚举的一种写法,我测试后感觉有些奇怪
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 @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 因为在 enum.EnumType 里面,给 TestEnum 增加了 __str__ 方法,你可以在 TestEnum.__dict__ 里面看到这个方法 |
12 tf2 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 类了,学到了,这就去改代码 |