Python中枚举的一个好用例是什么?

11

我已经写了大约3年的Python 2代码,虽然我长时间以来就知道枚举,但我们开始在项目中使用它们(回溯 - 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

到目前为止,我发现这个功能只有在文档字符串中才有用,虽然并不像我希望的那样有用。我可以声明我的形式参数期望一个Status枚举的成员,而不是明确地说允许的值是“active”和“inactive”(当存在更多状态时更有帮助)。

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

简而言之:何时使用枚举?


如果你使用字符串,你的 DocString 也可以写成“必须是类Status中定义的常量之一”。 - 5gon12eder
回答标题问题:Python 枚举,何时何地使用? - Ethan Furman
3个回答

7
一些要点:
  • 您的Enum类可以使用str作为mixin。
  • 一些数据库层允许将存储的数据转换为Python数据类型。
关于第一个要点:
class Status(str, Enum):
    active = 'active'
    inactive = 'inactive'

...

if value == Status.active:
    ...

第二点:
我在这方面没有太多经验,但我相信SQLAlchemy可以做到这一点。

6

我在GUI设计中最常使用枚举。想象一下你有一个单选按钮,如enter image description here

这表示一个固定选择列表,在幕后,它被枚举很好地表示。也就是说,如果用户选择了按钮2,则某些回调可以返回Enum.Choice.Choice2。这比返回int 2或字符串"choice 2"更好,因为后者没有什么可以在以后验证的东西。换句话说,如果您将"choice 2"更改为"user choice 2",则可能会破坏预期原始符号的下游组件。

把枚举看作是呈现静态选择集的便捷快捷方式,而不是创建样板对象类。

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

public void (Enum.Choice, mychoice)

替代

public void (String, mychoice)

在第二种情况下,用户可能需要事先知道mychoice应该是"foo""bar",但如果他们传入无效的"baz"会怎样?使用Enum将确保无法将无效输入传递给方法,因为Enum.Choice只会有foobar字段。如果你尝试创建baz Choice将无法成功。
抱歉,我走进了Java。这是否太离题而无法帮助?

1
您看到的问题是因为您的ORM没有将数据库值映射到Enum对象上。如果有,您就不必处理.value。
另一种选择是类似于:if Status(value) is Status.active:,因为构造函数从给定参数创建一个Enum对象。

好发现 @EthanFurman,我用手机打字有点马虎。我已经将 == 替换为 is - Josh J
啊,这就解释了大写的 If。 ;) - Ethan Furman
1
不太好,因为 Status(value) 可能会引发 ValueError 异常 :| - vlad-ardelean

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接