如何比较 Python 中的枚举?

新手上路,请多包涵

自 Python 3.4 起,存在 Enum 类。

我正在编写一个程序,其中一些常量具有特定的顺序,我想知道哪种方式最适合比较它们:

 class Information(Enum):
    ValueOnly = 0
    FirstDerivative = 1
    SecondDerivative = 2

现在有一个方法,需要将给定的 informationInformation 与不同的枚举进行比较:

 information = Information.FirstDerivative
print(value)
if information >= Information.FirstDerivative:
    print(jacobian)
if information >= Information.SecondDerivative:
    print(hessian)

直接比较不适用于枚举,所以有三种方法,我想知道哪一种是首选:

方法 1:使用值:

 if information.value >= Information.FirstDerivative.value:
     ...

方法 2:使用 IntEnum:

 class Information(IntEnum):
    ...

方法 3:根本不使用枚举:

 class Information:
    ValueOnly = 0
    FirstDerivative = 1
    SecondDerivative = 2

每种方法都有效,方法 1 有点冗长,而方法 2 使用不推荐的 IntEnum 类,而方法 3 似乎是在添加 Enum 之前这样做的方法。

我倾向于使用方法 1,但我不确定。

感谢您的任何建议!

原文由 Sebastian Werk 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 851
2 个回答

我之前没有遇到过枚举,所以我扫描了文档( https://docs.python.org/3/library/enum.html )……并找到了 OrderedEnum(第 8.13.13.2 节)这不是你想要的吗?从文档:

 >>> class Grade(OrderedEnum):
...     A = 5
...     B = 4
...     C = 3
...     D = 2
...     F = 1
...
>>> Grade.C < Grade.A
True

原文由 nigel222 发布,翻译遵循 CC BY-SA 3.0 许可协议

如果您想将它们与 Enum 一起使用,您应该始终实现丰富的比较运算符。使用 functools.total_ordering 类装饰器,您只需要实现一个 __eq__ 方法以及一个排序,例如 __lt__ 由于 enum.Enum 已经实现 __eq__ 这变得更加容易:

 >>> import enum
>>> from functools import total_ordering
>>> @total_ordering
... class Grade(enum.Enum):
...   A = 5
...   B = 4
...   C = 3
...   D = 2
...   F = 1
...   def __lt__(self, other):
...     if self.__class__ is other.__class__:
...       return self.value < other.value
...     return NotImplemented
...
>>> Grade.A >= Grade.B
True
>>> Grade.A >= 3
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unorderable types: Grade() >= int()

IntEnum 会发生可怕、可怕、可怕的事情。它主要是为了向后兼容而包含的,枚举过去是通过子类化实现的 int 。从 文档

对于绝大多数代码,强烈建议使用 Enum,因为 IntEnum 打破了枚举的某些语义承诺(通过与整数进行比较,从而传递给其他不相关的枚举)。它应该只在没有其他选择的特殊情况下使用;例如,当整数常量被枚举替换时,仍然需要整数的代码需要向后兼容。

这是您不想这样做的原因的示例:

 >>> class GradeNum(enum.IntEnum):
...   A = 5
...   B = 4
...   C = 3
...   D = 2
...   F = 1
...
>>> class Suit(enum.IntEnum):
...   spade = 4
...   heart = 3
...   diamond = 2
...   club = 1
...
>>> GradeNum.A >= GradeNum.B
True
>>> GradeNum.A >= 3
True
>>> GradeNum.B == Suit.spade
True
>>>

原文由 juanpa.arrivillaga 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题