2

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

但是我正在考虑的用例只是函数参数被限制为一组可能的值,这些值当前作为“魔术字符串”传递。所以在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,而不是使用它:

4

2 回答 2

1

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

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

于 2018-05-10T10:05:19.683 回答
0

好吧,关于代码的清晰度可能取决于个人和样式,但是 enum 使它更清晰,认为如果您需要更改要用作标志的字符串,您将不得不在使用和 enum 时重构所有代码,您只需要在枚举类中更改它。对我来说使用枚举是有意义的:

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)

这里有一个活生生的例子

于 2018-05-10T10:04:32.953 回答