在Python中互相推荐Enum成员

时间:2018-10-13 23:29:03

标签: python python-3.x

我在Python中定义了以下枚举:

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

我希望

print(Unit.GRAM.base_unit)
print(Unit.KILOGRAM.base_unit)

将返回

Unit.GRAM
Unit.GRAM

但是,我得到的却很混乱

Unit.GRAM
g

为什么会这样?

2 个答案:

答案 0 :(得分:2)

Python定义类的方式包括创建一个新的作用域,处理一堆语句(变量赋值,函数定义等),然后 then 实际上基于局部变量创建一个类对象在所有这些语句运行之后,它们就会存在。直到最后一步,什么都不会转换成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()

这样看,希望您可以说在定义KILOGRAM时,GRAM实际上只是一个字符串。直到最后一个阶段,它才成为Unit实例,在这里我称为(虚构)make_class()函数。 1


1 即使我上面使用的make_class函数实际上并不是以该名称存在,但它与Python的实际用法并没有太大不同,后者称为{{ 1}}或元类(在本例中为type s的元类)。

答案 1 :(得分:1)

DavidZ很好地解释了这个问题。

您需要解决的最后一点是:运行每个成员的__init__时,已经创建了Enum,因此您可以调用它:

self.base_unit = self if base_unit is None else self.__class__(base_unit)