根据文档,enum成员是单身人士.
>>> from enum import Enum
>>> class Potato(Enum):
... spud = 1234
... chat = 1234
...
>>> x = 1234
>>> y = 1234
>>> x is y
False
>>> x = Potato.spud
>>> y = Potato.chat
>>> x is y
True
>>> x.value is y.value
True
Run Code Online (Sandbox Code Playgroud)
这是否意味着我们也应该通过身份来比较它们,就像PEP8建议我们应该总是使用/不是,而不是像"无"这样的单身人士的平等算子?
到目前为止,我一直在使用平等算子,并且没有发现任何问题需要保证如PEP8警告的强烈措辞.如果有的话,为枚举实例使用相等的缺点究竟是什么?或者它只是一个微优化?
Jan*_*cke 12
来自https://docs.python.org/3/library/enum.html#module-enum:
在枚举中,可以通过身份对成员进行比较
特别是,来自https://docs.python.org/3/library/enum.html#comparisons:
枚举成员按身份进行比较
PEP 8 说:
与像 None 这样的单例的比较应该总是使用
isor来完成is not,而不是使用相等运算符。
我不同意 abarnert 的观点:这样做的原因并不是因为它们是内置的或以任何方式特殊。这是因为在这些情况下,您关心的是拥有该对象,而不是看起来像它的东西。
is None例如,在使用 时,您关心的是它是否是None您放在那里的,而不是None传入的不同值。这在实践中可能很困难(毕竟只有一个None),但有时确实很重要。
举个例子:
no_argument = object()
def foo(x=no_argument):
if x OP no_argument:
...
...
Run Code Online (Sandbox Code Playgroud)
如果OP是is,这就是完全惯用的代码。如果是==,那就不是。
出于同样的原因,您应该做出如下决定:
如果您希望与鸭子类型相等,例如IntEnum您可能想要子类化并覆盖一个枚举(例如,当您具有带有方法和其他附加功能的复杂枚举类型时),那么使用==.
当您使用枚举作为愚蠢的哨兵时,请使用is.
首先,我们可以肯定地排除掉x.value is y.value,因为它们不是单例,而是存储在属性中的完全普通的值。
但是呢x is y?
首先,我相信,PEP 8通过“像没有的单子一样”专门指的是固定的小型固定内置单例集,它们None在某种程度上很重要。有什么重要方法吗?为什么你要比较None有is?
可读性:if foo is None:读起来像是什么意思。在极少数情况下,您想与True其他真实值区分开来,其if spam is True:读起来要比更好if spam == True:,并且更明显的是,这不仅仅是== True不正确地遵循Python C ++编码标准的人所使用的轻浮。这可能适用于foo is Potato.spud,但不适用于x is y。
用作标记:None用于表示“值丢失”或“搜索失败”或类似情况。当然,不应在None本身可以作为值的情况下使用它。而且,如果有人创建一个实例比较等于的类None,则有可能在没有意识到的情况下遇到该问题。is None防止这种情况。这是即使有更多的问题True和False(再次,在那些极少数情况下,当你想区分它们),因为1 == True和0 == False。这个原因似乎在这里并不适用-如果是1 == Potato.spud,那只是因为您有意选择使用an IntEnum而不是an Enum,在这种情况下,这正是您想要的...
(准)关键字状态:这些年来None,朋友逐渐从完全正常的内置关键字迁移到关键字。符号的默认值不仅None总是单例,唯一可能的值就是单例。这意味着优化器,静态linter等可以对None代码中的含义进行假设,从而无法在运行时定义任何内容。同样,这个原因似乎并不适用。
性能:这根本不是要考虑的问题。在某些实现中,与进行比较可能会is比与进行比较更快,==但是这种情况在实际代码中几乎不可能发挥任何作用(或者,如果确实如此,则实际代码可能需要进行更高级别的优化,例如翻个列表)进入一组…)。
那么,结论是什么?
好吧,很难摆脱这里的观点,但是我认为这样说是合理的:
if devo is Potato.spud: 如果它使事情更具可读性是合理的,但是只要您在代码库中保持一致,就不会有人抱怨这两种方式。if x is y:,即使已知它们都是Potato对象,也不合理。if x.value is Potato.spud.value 是不合理的。