【问题标题】:Where is the init method invoked in enum classes?枚举类中调用的 init 方法在哪里?
【发布时间】:2022-01-19 21:42:20
【问题描述】:

我有一个像下面这样的课程。

from enum import Enum, unique
from typing import Tuple

@unique
class Test(Enum):
    v1: Tuple = (1, "value_1")
    v2: Tuple = (2, "value_2")

    def __init__(self, value_number: int, value_name: str) -> None:
        self.value_number = value_number
        self.value_name = value_name

    @classmethod
    def get_value_name_by_value_number(cls, number: int) -> str:
        for member in cls.__members__.values():
            if member.value_number == number:
                return member.value_name
        else:
            raise NotImplementedError()

if __name__ == '__main__':
    name = Test.get_value_name_by_value_number(number=2)
    print(name)

当我运行代码时,输​​出是正确的。但我不明白为什么它没有问题。据我所知,__init__ 方法是在创建实例时调用的。我调用的方法是classmethod,因此我没有创建对象并直接从类中调用它。所以__init__ 没有被调用。但是我的班级怎么知道member.value_numbermember.value_name 是什么?

【问题讨论】:

  • 这一切都由元类处理:github.com/python/cpython/blob/… 所以它发生在类创建期间。 enum 严重依赖元类魔法
  • 元素(v1v2)本身就是 Test 实例,将调用 __init__
  • 旁注:您的NotImplementedError 应该是ValueError

标签: python enums init


【解决方案1】:

在创建Test 类时,Enum 内部将创建所有枚举成员和manually call your __init__ method

enum_member.__init__(*args)

你会认为它只是在某个地方正常地实例化你的类,但是在 Enum 实现中发生了多少奇怪的魔法,结果证明这是行不通的。

【讨论】:

    最近更新 更多