Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 枚举实例是否应按标识或相等进行比较?_Python_Enums - Fatal编程技术网

Python 枚举实例是否应按标识或相等进行比较?

Python 枚举实例是否应按标识或相等进行比较?,python,enums,Python,Enums,根据文件 这是否意味着我们也应该通过身份来比较它们,正如PEP8所建议的那样,我们应该始终使用是/不是,并且永远不要使用“Singleton like None”的相等运算符 到目前为止,我一直在使用相等运算符,并没有注意到与此相关的任何问题,以保证像PEP8警告的那样使用强有力的措辞。对枚举实例使用相等性(如果有的话)的缺点到底是什么?或者这只是一个微观优化?首先,我们可以明确排除x.value是y.value,因为它们不是单例,它们是存储在属性中的非常普通的值 但是x是y呢 首先,我认为,P

根据文件

这是否意味着我们也应该通过身份来比较它们,正如PEP8所建议的那样,我们应该始终使用是/不是,并且永远不要使用“Singleton like None”的相等运算符


到目前为止,我一直在使用相等运算符,并没有注意到与此相关的任何问题,以保证像PEP8警告的那样使用强有力的措辞。对枚举实例使用相等性(如果有的话)的缺点到底是什么?或者这只是一个微观优化?

首先,我们可以明确排除
x.value是y.value
,因为它们不是单例,它们是存储在属性中的非常普通的值

但是x是y呢

首先,我认为,PEP 8所说的“像无一样的单例”,是指一小部分固定的内置单例,它们在某些重要方面像无一样。什么是重要的方式?为什么要将
None
is
进行比较

可读性:
如果foo为None:
的内容与它的意思相同。在您想区分代码> >真/代码>与其他真实值的情况下,<代码>如果垃圾邮件是真的:读取优于<代码>如果SPAM=true:<代码>,并且更明显地表明,这不是一个轻率的<代码> = =真/ <代码>,这是某人不正确地遵循Python中的C++编码标准所使用的。这可能适用于
foo is Potato.spud
,但在
x is y
中不太适用

用作哨兵:
None
用于表示“缺少值”或“搜索失败”或类似情况。当然,在
None
本身可以是值的情况下不应该使用它。如果有人创建了一个实例比较等于
None
的类,那么可能会在没有意识到的情况下遇到这个问题<代码>为无可防止出现这种情况。这对于
True
False
(同样,在您想要区分它们的罕见情况下)来说是一个更大的问题,因为
1==True
0==False
。如果
1==Potato.spud
,这个原因在这里似乎不适用,这只是因为您有意选择使用
IntEnum
而不是
Enum
,在这种情况下,这正是您想要的

(准)关键字状态:
None
,多年来,好友已逐渐从完全正常的内置项迁移到关键字。符号
None
的默认值不仅始终是singleton,唯一可能的值是singleton。这意味着优化器、静态linter等可以对
None
在代码中的含义进行假设,而在运行时定义的任何内容都不能这样做。同样,这个理由似乎并不适用

性能:这根本不是一个考虑因素。在某些实现中,与
is
相比,它可能比
=
更快,但这不太可能对实际代码产生任何影响(或者,如果确实如此,则实际代码可能需要更高级别的优化,如将列表转换为集合……)

那么,结论是什么

好吧,在这里很难摆脱一种观点,但我认为这样说是合理的:

  • 如果devo是土豆。spud:
    是合理的,如果它能让事情更可读,但只要你在代码库中保持一致,我认为任何人都不会抱怨
  • 如果x是y:
    ,即使它们都是
    对象,也是不合理的
  • 如果x.value是Potato.spud.value
    是不合理的
政治公众人物第8版说:

应始终使用
is
is not
进行与None等单例的比较,切勿使用相等运算符

我不同意abarnert的观点:这并不是因为它们是内置的或在任何方面都是特殊的。这是因为在这些情况下,你关心的是对象,而不是看起来像它的东西

例如,使用
is None
时,您关心的是您放在那里的
None
,而不是传入的其他
None
。这在实践中可能很困难(毕竟只有一个
),但有时确实很重要

例如:

no_argument = object()
def foo(x=no_argument):
    if x OP no_argument:
        ...
    ...
如果
OP
is
,则这是完全惯用的代码。如果它是
==
,则不是

出于同样的原因,您应做出如下决定:

  • 如果您希望使用相等于duck类型,例如使用
    IntEnum
    或您可能希望子类化和覆盖的枚举(例如,当您使用带有方法和其他附加项的复杂枚举类型时),则使用
    =
    是有意义的

  • 将枚举用作哑哨兵时,请使用
    is

来自:

在枚举中,可以按标识比较成员

特别是:

枚举成员按标识进行比较


请记住,
Enum
只是在3.4中添加的,PEP 8没有被重写;除非有人发出臭味(在bug跟踪器或
-dev
-ideas
列表上),否则它只会得到少量编辑。它甚至不建议在需要枚举时使用
Enum
如果垃圾邮件是真的
也可以避免
True==1
@user2357112什么时候会出现这种情况?@Veedrac:不经常,但是我们已经假设我们处于需要将
True
与布尔上下文中被认为是True的其他值区分开来的情况。对于那些其他数值来说,这并不是一个很大的延伸。也许在诸如实现某种通用JSON处理的情况下,您需要以不同的方式处理布尔值和数字,这可能很重要。@user2357112:同意,事实上,我怀疑区分
是真的<
no_argument = object()
def foo(x=no_argument):
    if x OP no_argument:
        ...
    ...