首页 > 解决方案 > 构造类类型的枚举值

问题描述

我有以下代码:

class Car:
  def __init__(self, id_):
    self.id = id_

class Train:
  def __init__(self, id_):
    self.id = id_

class TransportKind(Enum):
  One = Car
  Two = Train

class Transport:
  def __init__(self, transport_kind: TransportKind, other_value: int):
    self.transport_kind = transport_kind
    self.other_value = other_value

现在我想构建一个Transport

ts = Transport(transport_kind=TransportKind.One(id=5), other_value=2)

但是这是无效的,因为无法构造 Enum 值 ( TypeError: 'TransportKind' object is not callable)

如何构建 TransportKind 值?

标签: pythonpython-3.xclassenums

解决方案


枚举类型(在其他语言以及 Python 中)通常并不意味着类型本身具有数据。我也很困惑,因为传统上,您不希望枚举类型的名称被掩盖。枚举用于在一组离散的类型/属性中进行分类。传统上,您将有如下解决方案:

from enum import Enum

class TransportKind(Enum):
    Car = 1
    Train = 2

class Transport(object):
    def __init__(self, transport_kind: TransportKind, other_value: int, **extra_data):
        self.transport_kind = transport_kind
        self.other_value = other_value
        for k, v in extra_data.items():
            setattr(self, k, v)

...

ts = Transport(transport_kind=TransportKind.Car, other_value=2, id=5)

在某个地方,无论何时相关,您都会根据ts.transport_kind不同的行为和不同的预期属性进行调度。

也就是说,更传统的方法是简单的面向对象编程:

class Transport(object):
    def __init__(self, id: int, other_value: int):
        self.id = id
        self.other_value = other_value

class Car(Transport):
    pass

class Train(Transport):
    pass

...

ts = Car(other_value=2, id=5)

instanceof然后稍后使用基于类本身的调度(动态的,双重使用访问者模式,甚至只是一个简单的检查)。

如果您对按照您建议的方式做事如此死心塌地,它将涉及对Enum进行子类化,甚至对内部进行子类化EnumMeta并更改其行为,这很快就会变得非常混乱。

E:修正了我在第二个例子中所做的假设


推荐阅读