【问题标题】:Best way to use Python Enum or Dictionary for mapping constants and staying DRY with inference使用 Python Enum 或 Dictionary 映射常量并保持 DRY 推理的最佳方式
【发布时间】:2021-11-26 03:41:16
【问题描述】:

我刚开始使用 Python 进行服务器端编程(来自 TypeScript),为枚举键入 .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 来实现我想要的推理,让我的代码尽可能干燥,这样我就可以避免输入我的字符串?

注意:

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

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

【问题讨论】:

  • 如果你根本不继承Enum,那么带有字符串属性的类就会表现得如你所愿。那么Enum 中真的有一些您确实需要的功能吗?
  • 我不知道为什么你的问题会被否决,只要它是遵循 SO 准则的有效问题 - 它似乎确实如此。
  • Enum 的主要价值在于 编译器 可以捕捉到像Nroth 这样的错字。像"Nroth" 这样的字符串将不会被检测到,直到您的程序行为异常。 isEqual = CompassDirection.North == CompassDirection(x)。如果x 不是有效方向,您将立即收到错误消息。
  • 另一种选择是在函数中执行直接相等检查。这方便多了。例如,x = CompassDirection.NORTH; assert x is CompassDirection.NORTH # true。当然,这是假设你真的不需要检索枚举的值
  • 要检查 Enum 是否不是指定的成员或名称,您可以类似地使用is not 检查。

标签: python enums constants dry inference


【解决方案1】:

您的问题的直接解决方案是从str 以及Enum 继承1

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 Enumenum34 backportAdvanced Enumeration (aenum) 库的作者。

【讨论】:

  • 这太棒了!我也为StrEnum 感到兴奋,这听起来是个很酷的主意。
猜你喜欢
  • 2018-04-03
  • 1970-01-01
  • 1970-01-01
  • 2023-03-07
  • 2022-06-10
  • 1970-01-01
  • 2016-12-29
  • 1970-01-01
  • 2023-01-23
相关资源
最近更新 更多