Em um comentário sobre essa pergunta , vi uma declaração que recomendava o uso de
result is not None
vs
result != None
Eu queria saber qual é a diferença, e por que um pode ser recomendado em detrimento do outro?
Em um comentário sobre essa pergunta , vi uma declaração que recomendava o uso de
result is not None
vs
result != None
Eu queria saber qual é a diferença, e por que um pode ser recomendado em detrimento do outro?
Respostas:
==
é um teste de igualdade . Ele verifica se o lado direito e o lado esquerdo são iguais objectos (de acordo com as suas__eq__
ou__cmp__
métodos.)is
é um teste de identidade . Ele verifica se o lado direito e o lado esquerdo são o mesmo objeto. Nenhuma chamada de método é feita, os objetos não podem influenciar ais
operação.Você usa
is
(eis not
) para singletons, comoNone
, onde você não se importa com objetos que possam querer fingir estarNone
ou onde deseja proteger contra objetos quebrados ao serem comparadosNone
.fonte
None
tem poucos métodos e quase nenhum atributo. Se o seu__eq__
teste esperava um método ou atributo, ele pode quebrar.def __eq__( self, other ): return self.size == other.size
. Por exemplo, irá quebrar seother
acontecerNone
.is
é como o Java==
. O Python==
é como o Java.equals()
. Claro que isso só ajuda se você conhece Java.is
é como===
(muito igual) e, inversamente,is not
é como!==
(não é exatamente igual).is not
um único operador ou está apenas negando o resultado deis
gostar internamentenot foo is bar
?Primeiro, deixe-me passar por alguns termos. Se você apenas deseja que sua pergunta seja respondida, role para baixo até "Respondendo a sua pergunta".
Definições
Identidade do objeto : ao criar um objeto, você pode atribuí-lo a uma variável. Você também pode atribuí-lo a outra variável. E outro.
Neste caso,
cancel
,close
, edismiss
todos se referem ao mesmo objeto na memória. Você criou apenas umButton
objeto e todas as três variáveis se referem a esse único objeto. Dizemos quecancel
,close
edismiss
todos se referem a idênticas objetos; isto é, eles se referem a um único objeto.Igualdade de objetos : quando você compara dois objetos, geralmente não se importa que se refira exatamente ao mesmo objeto na memória. Com a igualdade de objetos, você pode definir suas próprias regras para comparar dois objetos. Quando você escreve
if a == b:
, você está dizendo essencialmenteif a.__eq__(b):
. Isso permite definir um__eq__
método ema
para que você possa usar sua própria lógica de comparação.Justificativa para comparações de igualdade
Justificativa: Dois objetos têm exatamente os mesmos dados, mas não são idênticos. (Eles não são o mesmo objeto na memória.) Exemplo: Strings
Nota: Eu uso cadeias unicode aqui porque o Python é inteligente o suficiente para reutilizar cadeias regulares sem criar novas na memória.
Aqui, eu tenho duas cadeias unicode,
a
eb
. Eles têm exatamente o mesmo conteúdo, mas não são o mesmo objeto na memória. No entanto, quando os comparamos, queremos que eles comparem iguais. O que está acontecendo aqui é que o objeto unicode implementou o__eq__
método.Nota:
__eq__
onunicode
é definitivamente implementado com mais eficiência do que isso.Justificativa: Dois objetos têm dados diferentes, mas são considerados o mesmo objeto se alguns dados importantes forem os mesmos. Exemplo: a maioria dos tipos de dados do modelo
Aqui, tenho dois monitores Dell
a
eb
. Eles têm a mesma marca e modelo. No entanto, eles não têm os mesmos dados nem o mesmo objeto na memória. No entanto, quando os comparamos, queremos que eles comparem iguais. O que está acontecendo aqui é que o objeto Monitor implementou o__eq__
método.Respondendo sua pergunta
Ao comparar com
None
, use sempreis not
. Nenhum é um singleton em Python - existe apenas uma instância na memória.Comparando a identidade , isso pode ser realizado muito rapidamente. O Python verifica se o objeto ao qual você está se referindo tem o mesmo endereço de memória que o objeto None global - uma comparação muito, muito rápida de dois números.
Ao comparar a igualdade , o Python precisa verificar se o seu objeto possui um
__eq__
método. Caso contrário, examina cada superclasse procurando um__eq__
método. Se encontrar, Python o chama. Isso é especialmente ruim se o__eq__
método for lento e não retornar imediatamente quando perceber que o outro objeto estáNone
.Você não implementou
__eq__
? Então o Python provavelmente encontrará o__eq__
métodoobject
e o utilizará - o que apenas verifica a identidade do objeto de qualquer maneira.Ao comparar a maioria das outras coisas em Python, você estará usando
!=
.fonte
Considere o seguinte:
fonte
None
é um singleton, portanto, a comparação de identidade sempre funcionará, enquanto um objeto pode falsificar a comparação de igualdade via.__eq__()
.fonte
None
, mas um comportamento incorretoNone
pode ocorrer como um efeito colateral da implementação da igualdade contra outros tipos. Não são tantas implicações de segurança, mas apenas implicações de correção.Alguns objetos são singletons e, portanto,
is
com eles é equivalente a==
. A maioria não é.fonte
()
e1
não são inerentemente singletons.-NSMALLNEGINTS <= n <= NSMALLPOSINTS
) e as tuplas vazias são singletons. Na verdade, não está documentado nem garantido, mas é improvável que mude.