互相推荐枚举成员

dzi*_*iou 6 python python-3.x

我在Python中定义了以下Enum:

class Unit(Enum):
    GRAM = ("g")
    KILOGRAM = ("kg", GRAM, 1000.0)

    def __init__(self, symbol, base_unit = None, multiplier = 1.0):
        self.symbol = symbol
        self.multiplier = multiplier
        self.base_unit = self if base_unit is None else base_unit
Run Code Online (Sandbox Code Playgroud)

我希望

print(Unit.GRAM.base_unit)
print(Unit.KILOGRAM.base_unit)
Run Code Online (Sandbox Code Playgroud)

将返回

Unit.GRAM
Unit.GRAM
Run Code Online (Sandbox Code Playgroud)

但是,我得到的是相当混乱的

Unit.GRAM
g
Run Code Online (Sandbox Code Playgroud)

为什么会这样呢?

Dav*_*d Z 3

Python 定义类的方式涉及创建一个新作用域、处理一堆语句(变量赋值、函数定义等),然后根据所有这些语句运行后存在的局部变量实际创建一个类对象。Enum在最后一步之前,没有任何内容会转换为实例。

你可以这样理解:

def make_class_Unit():
  GRAM = ("g")
  KILOGRAM = ("kg", GRAM, 1000.0)

  def __init__(self, symbol, base_unit = None, multiplier = 1.0):
    self.symbol = symbol
    self.multiplier = multiplier
    self.base_unit = self if base_unit is None else base_unit
  return make_class(name='Unit', base=Enum, contents=locals())

Unit = make_class_Unit()
Run Code Online (Sandbox Code Playgroud)

这样看,希望你能看出,在定义时KILOGRAMGRAM它实际上只是一个字符串。Unit直到最后一个阶段,我称之为(虚构的)函数,它才成为一个实例make_class()1


1尽管make_class我上面使用的函数实际上并不存在于该名称下,但它与 Python 实际所做的并没有太大不同,即调用type或元类的构造函数(在本例中是 s 的元类Enum)。