【问题标题】:What's a good use case for enums in python?python中枚举的好用例是什么?
【发布时间】:2017-01-18 17:18:04
【问题描述】:

我已经编写 Python 2 代码大约 3 年了,虽然我很早就知道枚举,但我们已经开始在我们的项目中使用它们(向后移植 - pypi 包 enum34 )。

我想了解何时使用它们。

我们开始使用它们的一个地方是将一些 postgres 数据库级枚举映射到 python 枚举。因此我们有这个枚举类

class Status(enum.Enum):
    active = 'active'
    inactive = 'inactive'

但是当使用这些时,我们最终会像这样使用它们:

if value == Status.active.value:
    ...

因此在这种情况下使用枚举比使用更简单的类(像这样)没有帮助

class Status(object):
    active = 'active'
    inactive = 'inactive'

因为我们可以更轻松地使用它,例如 value == Status.active

到目前为止,我发现这个有用的唯一地方 - 虽然没有我想要的那么有用 - 是在文档字符串中。与其明确说允许的值是“活动”和“不活动”,我可以声明我的形式参数需要一个状态枚举的成员(当存在更多状态时更有帮助)

所以我真的不知道它们的确切用例是什么 - 我不知道它们比字符串常量更好。

简而言之:什么时候使用枚举?

【问题讨论】:

标签: python enums


【解决方案1】:

几点:

  • 您的Enum 类可以使用str 作为mixin。
  • 某些数据库层允许将存储的数据转换为 Python 数据类型。

第一点:

class Status(str, Enum):
    active = 'active'
    inactive = 'inactive'

...

if value == Status.active:
    ...

关于第二点:

我在这方面的经验很少,但我相信 SQLAlchemy 会做到这一点。

【讨论】:

    【解决方案2】:

    我在 GUI 设计中最常使用 Enum。假设您有一个单选按钮,例如

    这代表了一个固定选项的列表,所以在底层,它很好地由一个枚举来表示。也就是说,如果用户选择按钮 2,则某些回调可能会返回 Enum.Choice.Choice2。这比返回int 2 或字符串"choice 2" 要好,因为以后无需验证这些。换句话说,如果您将 "choice 2" 更改为 "user choice 2",您可能会破坏期望原始符号的下游组件。

    将 Enum 视为呈现一组静态选择的便捷快捷方式,而不是创建样板对象类。

    我发现 Java(以及我认为的其他静态类型语言)中的 Enum 更有用,因为您可以在方法签名中声明它们。例如,一个方法可能有签名,

    public void (Enum.Choice, mychoice)
    

    代替

    public void (String, mychoice)
    

    在第二种情况下,用户可能需要提前知道mychoice应该是"foo"或者"bar",但是如果他们传入"baz",这是无效的。使用Enum 将确保无法将无效输入传递给方法,因为Enum.Choice 将只有字段foobar。如果您尝试过,您将无法创建 baz 选择。

    抱歉,我误入了 Java。这是不是太离题了,没有帮助?

    【讨论】:

      【解决方案3】:

      您看到的问题是因为您的 ORM 没有将数据库值映射到您的 Enum 对象。如果是这样,您就不必处理.value

      另一种选择是:

      if Status(value) is Status.active: 因为构造函数从给定的参数创建了一个枚举。

      【讨论】:

      • 好消息@EthanFurman,我是用手机输入的,很草率。我已将== 换成is
      • 啊,这解释了大写If。 ;)
      • 不太好,因为Status(value) 可以提出ValueError :|
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-12-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多