1

编辑:我已经从原始问题中大量编辑了这个问题,以专注于 Enum 在这种情况下的优势(该问题主要基于意见而被搁置)


我理解在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

1 回答 1

2

我不知道我的方式是否是pythonic。但我可以这样使用:

string_mode = {
    'l': lambda s: s.lower(),
    'u': lambda s: s.upper(),
    'c': lambda s: s.capitalize(),
    't': lambda s: s.title(),
    's': lambda s: s.swapcase()
}

for mode in string_mode:
    print(string_mode.get(mode, lambda s: s)("RaNdoM CAse StRING"))

根据@Yakym Pirozhenko 的评论,我们可以使用更pythonic 的方式来做到这一点:

string_mode = {
    'l': str.lower,
    'u': str.upper,
    'c': str.capitalize,
    't': str.title,
    's': str.swapcase
}

for mode in string_mode:
    print(string_mode.get(mode, lambda s: s)("RaNdoM CAse StRING"))

此外,我们也可以使用一个函数:

def string_mode(string, mode='default'):
    return {
        'l': str.lower,
        'u': str.upper,
        'c': str.capitalize,
        't': str.title,
        's': str.swapcase
    }.get(mode, lambda s:s)(string)
于 2018-05-05T00:39:54.067 回答