Nenhuma comparação em Python: devo usar "is" ou ==?


213

Meu editor me avisa quando comparo my_var == None, mas nenhum aviso quando uso my_var is None.

Fiz um teste no shell do Python e determinei que ambas são sintaxe válida, mas meu editor parece estar dizendo que my_var is Noneé o preferido.

É esse o caso? Se sim, por quê?


7
PEP 8 diz em algum lugar que você deve comparar a singletons usando is- python.org/dev/peps/pep-0008/#programming-recommendations
Volatilidade

2
Esse pôster está falando sobre o Python 3, e minha pergunta é sobre o Python 2.x. Não tenho certeza se essa é uma diferença grande o suficiente para garantir os dois remanescentes, mas editei a pergunta para incluir isso apenas por precaução.
Clay Wardell

2
Não acho que essa pergunta seja realmente uma duplicata. O outro foi sobre == vs em geral, este é sobre None em particular.
IJ Kennedy

Respostas:


254

Resumo:

Use isquando quiser verificar a identidade de um objeto (por exemplo, verificar se varexiste None). Use ==quando quiser verificar a igualdade (por exemplo, é varigual a 3?).

Explicação:

Você pode ter classes personalizadas onde my_var == NoneretornaráTrue

por exemplo:

class Negator(object):
    def __eq__(self,other):
        return not other

thing = Negator()
print thing == None    #True
print thing is None    #False

isverifica a identidade do objeto . Há apenas um objeto None; portanto, quando você faz isso my_var is None, verifica se eles realmente são o mesmo objeto (não apenas objetos equivalentes )

Em outras palavras, ==é uma verificação de equivalência (que é definida de objeto para objeto), enquanto isverifica a identidade do objeto:

lst = [1,2,3]
lst == lst[:]  # This is True since the lists are "equivalent"
lst is lst[:]  # This is False since they're actually different objects

22
Quando é is Nonediferente == None?
Blender

11
@Blender No caso mencionado. __eq__pode ser definido de qualquer forma, mas o comportamento deis não pode ser alterado tão facilmente.
Lev Levitsky

5
@LevLevitsky: Um dos exemplos de usos do Mython foi "estender os protocolos para que qualquer operador possa ser sobrecarregado, mesmo is". Depois de um comentário nas listas, ele mudou para "... mesmo is(mas apenas se você for louco)".
abarnert

1
+1, mas seria ainda melhor se essa resposta incluísse a referência do PEP 8 que os outros fazem (além de explicar por que a decisão por trás do PEP 8 faz sentido, o que já faz).
abarnert

3
@abarnert - eu nem sabia que o PEP 8 fez uma recomendação aqui. O ponto é que eles são operadores diferentes que fazem coisas diferentes. Pode haver casos em que, object == Nonena verdade, seja o idioma correto (embora eu não consiga pensar em nada de fora da minha cabeça). Você só precisa saber o que está fazendo.
mgilson

127

isé geralmente preferido ao comparar objetos arbitrários a singletons, Noneporque é mais rápido e previsível. issempre se compara à identidade do objeto, enquanto o que ==fará depende do tipo exato dos operandos e até da ordem deles.

Esta recomendação é apoiada pelo PEP 8 , que declara explicitamente que "comparações com singletons como None devem sempre ser feitas com isou is notnunca com os operadores de igualdade".


6
Obrigado por postar isso; a resposta aceita faz alguns pontos interessantes, mas a sua responde à pergunta muito mais diretamente.
26417 Luke Davis

Parece estranho confiar no que é essencialmente um detalhe de implementação. Por que eu deveria me importar com quantas instâncias de NoneType existem?
usar o seguinte

@BallpointBen Porque é não um detalhe de implementação - há apenas um Noneobjeto sob o constante global None. Se alguma coisa, NoneTypeé um detalhe de implementação porque o Nonesingleton deve ter algum tipo. (O fato de que você não pode criar instâncias desse tipo é uma boa indicação de que a sua uma instância está destinado a ser um singleton.)
user4815162342

@ BallpointBen Acho que o ponto principal é que o Python possui um forte conceito de identidade de objeto. Se você quiser verificar se um objeto compara igual a None, por todos os meios utilizar obj == None. Se você deseja verificar se um objeto é None , use obj is None. O ponto da recomendação do PEP 8 (e desta resposta) é que a maioria das pessoas deseja a última quando deseja verificar Nenhuma, e também é mais rápido e mais claro.
precisa saber é o seguinte

Nonetambém é diferente dos objetos armazenados em cache, como 0outros inteiros pequenos, em que o cache é realmente um detalhe da implementação. A diferença é que um número inteiro tem valor intrínseco, que fornece suas propriedades e pode ser calculado. Por outro lado, Nonenão tem nenhum estado, é apenas a sua identidade que importa e o torna especial.
usuário4815162342

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.