使用 Python Enum 或 Dictionary 映射常量并通过推理保持 DRY 的最佳方法

Best way to use Python Enum or Dictionary for mapping constants and staying DRY with inference

我刚开始使用 Python 进行服务器端编程(来自 TypeScript),为 Enum 输入 .value 的冗长让我考虑根本不使用它。

在 TypeScript 中,枚举的值是这样检索的..

enum CompassDirection {
  North = "North",
}

// I do not have to ask for the value
const isEqual = CompassDirection.North === "North" ? true : false

console.log(isEqual) // returns true 

但在 Python 中,我认为检索值的唯一方法是像这样使用 .value..

from enum import Enum

class CompassDirection(Enum):
    NORTH = 'NORTH'

isEqual = CompassDirection.NORTH == 'NORTH'
print(isEqual) // false

isEqual = CompassDirection.NORTH.value == 'NORTH'
print(isEqual) // true

我使用 Enum 的目的是进行推理,因此我不必在我的代码中重复键入诸如“NORTH”之类的字符串。

如果我做了一个函数,我也必须在任何地方调用它 - 例如


def get_enum_value(enum): 
   return enum.value

# Calling this every time I want to use the enum.
get_enum_value(CompassDirection.NORTH)
get_enum_value(XEnum.Value)
get_enum_value(YEnum.Value)

然而,如果我不这样做,我就会在各处重复输入 .value,我发现这违反直觉可能是因为我的 TypeScript 偏见。

有没有一种方法可以使用 Enum 或 Dictionary 实现我想要的推理,让我的代码尽可能干燥,这样我就可以避免输入字符串?

注:

我不介意创建一些常量,但我可以看到我的导入对于代码拆分/重用来说变得冗长。

我错过了什么吗?我想尽快了解这一点。

您的问题的直接解决方案是从 str 以及 Enum1:

继承
class CompassDirection(str, Enum):
    NORTH = 'NORTH'

>>> print(CompassDirection.NORTH == 'NORTH')
True

长期的解决方案是意识到你不应该再使用字符串,而是枚举成员,并使用 is:

somevar = CompassDirections.NORTH
#
# some intervening code
#
print(somevar is CompassDirections.NORTH)
# True

如果从用户、配置文件等处获取输入,您应该只需要处理字符串 "NORTH",然后您会希望立即转换为枚举:

result = input('Enter direction')
result = CompassDirection(result.upper())

1 Python 3.11 将有一个 StrEnum 类型,这将确保值已经是 str 类型。


披露:我是 Python stdlib Enum, the enum34 backport, and the Advanced Enumeration (aenum) 库的作者。