当不对基础值进行编码时,使用 Enum 有什么优势?

What advantage does using an Enum bring when it's not encoding underlying values?

我理解在将人类可读字符串转换为基础(例如数字)值时使用 Enum 的意义,在 [=22 中使用 FederalHoliday class =] 就是一个很好的例子。

但我正在考虑的用例只是将函数参数限制为一组可能的值,这些值当前作为 "magic strings" 传递。所以在这里实现 Enum 并不会真正提高代码的可读性(如果有的话,它会使代码更加混乱)。将一个字符串变成 Enum,只是为了比较实际上相同的字符串(即 Enum 的名称)感觉有点矫枉过正。

列出了枚举的一般优点,但我不确定其中有多少适用于这种情况。

为了澄清我的意思,这里有一个例子,它有一个函数,它打印一个由 mode:

指定的特定大小写的字符串
def print_my_string(my_string, mode):
    if mode == 'l':
        print(my_string.lower())
    elif mode == 'u':
        print(my_string.upper())
    elif mode == 'c':
        print(my_string.capitalize())
    else:
        raise ValueError("Unrecognised mode")

要查看实际效果,运行 这个:

for mode in ['l', 'u', 'c']:
    print_my_string("RaNdoM CAse StRING", mode)

给出:

random case string
RANDOM CASE STRING
Random case string

所以我的问题是:

当字符串不代表下面的另一个值时,Enum 有什么优势?有什么方法可以使代码更健壮吗? 添加什么吗?


我读过的其他内容:

一般来说主要是关于 Enums,尤其是当字符串表示下面的另一个值时:

这似乎有一个类似于我的例子(在 Enums are interoperable 下),但我很难理解围绕它的技术讨论,它只显示设置 Enum,未使用它:

好吧,关于代码的清晰度可能取决于人和风格,但枚举使它更清晰,认为如果您需要更改要用作标志的字符串,则必须在使用和时重构所有代码枚举你只需要在枚举 class 中更改它。 对我来说使用枚举是有意义的:

from enum import Enum

class PrintFlag(Enum):
  L = "lower"
  U = "upper"
  C = "capitalize"

def print_my_string(my_string, mode):
    action_dict = {
      PrintFlag.L : str.lower,
      PrintFlag.U : str.upper,
      PrintFlag.C : str.capitalize,
    }
    try:
      print(action_dict[mode](my_string))
    except KeyError:
      raise ValueError("Unrecognised mode")


for mode in PrintFlag:
    print_my_string("RaNdoM CAse StRING", mode)

这里有一个live example

你是对的,枚举不是一种静态类型的语言,枚举的好处在 Python 中并不那么强大。许多 API 仍然使用字符串来处理这些事情,而且很好。但是我认为它仍然有好处,特别是从 IDE 支持(自动完成)和静态分析(代码检查)的角度来看。想象一下,您有一个函数可以让您使用不同的方法计算向量的范数。选项 'Euclidean''Absolute''Manhattan''EUCLIDEAN''ABSOLUTE_VALUE''TAXICAB' 还是只是“e”、“a',和 'm'?如果你有一个枚举和一个足够好的 IDE,你可以写 NormType. 然后按 Ctrl+Space 来查看选项,而不必再次查看文档。如果你写错了,代码 linter 可能会让你知道。此外,如果您碰巧重命名其中一个选项,应该更容易找到所有需要更改的地方。

也就是说,我同意在某些情况下它可能只会使代码更加混乱。在您的示例中,这些选项可能足够简单,可以毫无问题地使用字符串。无论如何,当在多个地方使用枚举时,枚举的好处变得更加相关,例如具有相似参数的多个函数,您希望在这些地方强制统一并避免代码中愚蠢的字符串拼写错误。很难证明对单个函数的单个参数需要枚举。