Existe alguma diferença entre “foo is None” e “foo == None”?

StackOverflow https://stackoverflow.com/questions/26595

  •  09-06-2019
  •  | 
  •  

Pergunta

Existe alguma diferença entre:

if foo is None: pass

e

if foo == None: pass

A convenção que vi na maioria dos códigos Python (e no código que eu mesmo escrevo) é a primeira, mas recentemente me deparei com um código que usa a última.None é uma instância (e a única instância, IIRC) de NoneType, então não deveria importar, certo?Há alguma circunstância em que isso possa acontecer?

Foi útil?

Solução

is sempre retorna True se comparar a mesma instância do objeto

Enquanto == é finalmente determinado pelo __eq__() método

ou seja


>>> class Foo(object):
       def __eq__(self, other):
           return True

>>> f = Foo()
>>> f == None
True
>>> f is None
False

Outras dicas

Você pode querer ler isso identidade e equivalência de objeto.

A instrução 'is' é usada para identidade do objeto, ela verifica se os objetos se referem à mesma instância (mesmo endereço na memória).

E a declaração '==' refere-se à igualdade (mesmo valor).

Uma palavra de cautela:

if foo:
  # do something

É não Exatamente o mesmo que:

if x is not None:
  # do something

O primeiro é um teste de valor booleano e pode ser avaliado como falso em diferentes contextos.Há uma série de coisas que representam falso em testes de valor booleano, por exemplo, contêineres vazios, valores booleanos.Nenhum também é avaliado como falso nesta situação, mas outras coisas também o são.

(ob1 is ob2) igual a (id(ob1) == id(ob2))

A razão foo is None é a maneira preferida é que você esteja manipulando um objeto que define seu próprio __eq__, e isso define o objeto como igual a None.Então, use sempre foo is None se você precisa ver se é de fato None.

Não há diferença porque objetos idênticos serão naturalmente iguais.No entanto, PEP 8 afirma claramente que você deve usar is:

Comparações com singletons como None devem sempre ser feitas com is ou not is, nunca com os operadores de igualdade.

is testes de identidade, não igualdade.Para sua declaração foo is none, Python simplesmente compara o endereço de memória dos objetos.Isso significa que você está fazendo a pergunta "Tenho dois nomes para o mesmo objeto?"

== por outro lado, testes de igualdade, conforme determinado pelo __eq__() método.Não se importa com identidade.

In [102]: x, y, z = 2, 2, 2.0

In [103]: id(x), id(y), id(z)
Out[103]: (38641984, 38641984, 48420880)

In [104]: x is y
Out[104]: True

In [105]: x == y
Out[105]: True

In [106]: x is z
Out[106]: False

In [107]: x == z
Out[107]: True

None é um operador singleton.Então None is None é sempre verdade.

In [101]: None is None
Out[101]: True

Para None não deveria haver diferença entre igualdade (==) e identidade (é).O NoneType provavelmente retorna identidade para igualdade.Como None é a única instância que você pode fazer de NoneType (acho que isso é verdade), as duas operações são iguais.No caso de outros tipos, nem sempre é esse o caso.Por exemplo:

list1 = [1, 2, 3]
list2 = [1, 2, 3]
if list1==list2: print "Equal"
if list1 is list2: print "Same"

Isso imprimiria "Igual", pois as listas possuem uma operação de comparação que não é o retorno padrão da identidade.

@Jasão:

Eu recomendo usar algo mais parecido com

if foo:
    #foo isn't None
else:
    #foo is None

Não gosto de usar "if foo:" a menos que foo realmente represente um valor booleano (ou seja,0 ou 1).Se foo for uma string ou um objeto ou qualquer outra coisa, "if foo:" pode funcionar, mas parece um atalho preguiçoso para mim.Se você estiver verificando se x é Nenhum, diga "se x é Nenhum:".

Mais alguns detalhes:

  1. O is cláusula realmente verifica se os dois objectS estão no mesmo local de memória ou não.ou seja, se ambos apontam para o mesmo local de memória e têm o mesmo id.

  2. Como consequência de 1, is garante se, ou não, os dois representados lexicamente objects têm atributos idênticos (atributos-de-atributos...) ou não

  3. Instanciação de tipos primitivos como bool, int, string(com algumas exceções), NoneType ter o mesmo valor estará sempre no mesmo local de memória.

Por exemplo.

>>> int(1) is int(1)
True
>>> str("abcd") is str("abcd")
True
>>> bool(1) is bool(2)
True
>>> bool(0) is bool(0)
True
>>> bool(0)
False
>>> bool(1)
True

E desde NoneType só pode ter uma instância de si mesmo na tabela de "pesquisa" do python, portanto, o primeiro e o último são mais um estilo de programação do desenvolvedor que escreveu o código (talvez para consistência) em vez de ter qualquer razão lógica sutil para escolher um sobre o outro.

A conclusão de John Machin de que None é um singleton é uma conclusão reforçada por este código.

>>> x = None
>>> y = None
>>> x == y
True
>>> x is y
True
>>> 

Desde None é um singleton, x == None e x is None teria o mesmo resultado.No entanto, na minha opinião estética, x == None é melhor.

a is b # returns true if they a and b are true alias
a == b # returns true if they are true alias or they have values that are deemed equivalence 


a = [1,3,4]
b = a[:] #creating copy of list
a is b # if gives false
False
a == b # gives true
True
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top