E a razão para a escolha egg is Nonesobre egg == None: O último pode ser sobrecarregado, e é provável que quebrar quando comparando objeto válido com Nenhum (depende de como ele é implementado, mas você não espera que todos a tomar comparações com None em conta, não é?) , enquanto issempre funciona da mesma maneira.
94
por que os designers de python não escolheram "null". Só tem que ser diferente, não é! ;)
Vidar 26/03
35
@Vidar 'None' não é a falta de um objeto (como 'null' é, uma referência nula), é um objeto real. Você nunca receberá um objeto 'None' passando para um objeto que é de um tipo de coisa diferente de 'NoneType'. Também não é um conceito de linguagem. Não está embutido no Python, é parte da biblioteca padrão do Python. Nenhum! == (ahem) Nulo
Rushyo
11
@ naught101 Não serviria para nada; como não há conceito de ponteiros. Se você estiver usando a biblioteca ctypes, None será usado como sinônimo de endereço zero, mas ainda não existe o conceito de linguagem de uma 'referência nula'. No Python, você sempre fazia referência a algum tipo de objeto, mesmo que esse objeto seja Nenhum. Eu suspeito que isso simplifique bastante o idioma.
Rushyo 02/09
5
ótima apresentação explicando o 'erro de bilhão de dólares' que é a referência nula: infoq.com/presentations/… . Outras opções em vez de nulo são os tipos Opções ou Talvez (personalizado).
Michael Trouw
135
NoneNulo do Python?
Não existe nullno Python, mas sim None. Como já foi dito, a maneira mais precisa de testar se algo foi dado Nonecomo valor é usar o isoperador de identidade, que testa se duas variáveis se referem ao mesmo objeto.
Noneé a única instância da classe NoneTypee qualquer tentativa adicional de instanciar essa classe retornará o mesmo objeto, o que cria Noneum singleton. Os recém-chegados ao Python costumam ver mensagens de erro que mencionam NoneTypee se perguntam o que é. É minha opinião pessoal que essas mensagens poderiam simplesmente ser mencionadas Nonepelo nome porque, como veremos em breve, Nonedeixa pouco espaço para a ambiguidade. Portanto, se você vir alguma TypeErrormensagem que mencione que NoneTypenão pode ou não pode fazer isso, saiba que é simplesmente aquela Noneque estava sendo usada de uma maneira que não pode.
Além disso, Noneé uma constante interna, assim que você inicia o Python, ele está disponível para uso em qualquer lugar, seja no módulo, na classe ou na função. NoneTypepor outro lado, não, você precisa obter uma referência a ele primeiro consultando Nonesua classe.
>>>NoneTypeNameError: name 'NoneType'isnot defined
>>> type(None)NoneType
Você pode verificar Nonea singularidade da função de identidade do Python id(). Retorna o número único atribuído a um objeto, cada objeto possui um. Se o id de duas variáveis for o mesmo, elas apontam de fato para o mesmo objeto.
Em uma versão muito mais antiga do Python (anterior à 2.4), era possível reatribuir None, mas não mais. Nem mesmo como um atributo de classe ou nos limites de uma função.
# In Python 2.7>>>classSomeClass(object):...def my_fnc(self):... self.None='foo'SyntaxError: cannot assign to None>>>def my_fnc():None='foo'SyntaxError: cannot assign to None# In Python 3.5>>>classSomeClass:...def my_fnc(self):... self.None='foo'SyntaxError: invalid syntax
>>>def my_fnc():None='foo'SyntaxError: cannot assign to keyword
Portanto, é seguro assumir que todas as Nonereferências são iguais. Não há "costume" None.
Para testar o Noneuso do isoperador
Ao escrever o código, você pode tentar testar o Noneness dessa maneira:
if value==None:pass
Ou para testar falsidade como esta
ifnot value:pass
Você precisa entender as implicações e por que geralmente é uma boa idéia ser explícito.
Caso 1: testando se um valor é None
por que fazer isso
value isNone
ao invés de
value==None
O primeiro é equivalente a:
id(value)==id(None)
Considerando que a expressão value==Noneé de fato aplicada assim
value.__eq__(None)
se o valor realmente for None, você obterá o que esperava.
Na maioria dos casos comuns, o resultado será o mesmo, mas o __eq__()método abre uma porta que anula qualquer garantia de precisão, pois pode ser substituída em uma classe para fornecer um comportamento especial.
Considere esta classe.
>>>classEmpty(object):...def __eq__(self, other):...returnnot other
Então você experimenta Nonee funciona
>>> empty =Empty()>>> empty==NoneTrue
Mas também funciona na string vazia
>>> empty==''True
E ainda
>>>''==NoneFalse>>> empty isNoneFalse
Caso 2: usando Nonecomo um booleano
Os dois testes a seguir
if value:# do somethingifnot value:# do something
são de fato avaliados como
if bool(value):# do somethingifnot bool(value):# do something
Noneé um "falsey", significando que, se convertido em um booleano, ele retornará Falsee, se aplicado, o notoperador retornará True. Observe, no entanto, que não é uma propriedade exclusiva None. Além de Falsesi mesma, a propriedade é compartilhada por listas vazias, tuplas, conjuntos, dictos, seqüências de caracteres, além de 0 e todos os objetos de classes que implementam o __bool__()método mágico para retornar False.
>>> bool(None)False>>>notNoneTrue>>> bool([])False>>>not[]True>>>classMyFalsey(object):...def __bool__(self):...returnFalse>>> f =MyFalsey()>>> bool(f)False>>>not f
True
Portanto, ao testar variáveis da seguinte maneira, fique atento ao que você está incluindo ou excluindo do teste:
def some_function(value=None):ifnot value:
value = init_value()
Acima, você quis chamar init_value()quando o valor está definido especificamente para None, ou você quis dizer que um valor definido como 0, ou a sequência vazia ou uma lista vazia também deveria acionar a inicialização. Como eu disse, fique atento. Como geralmente é o caso explícito em Python, é melhor que implícito .
None na prática
None usado como um valor de sinal
Nonetem um status especial em Python. É um valor de linha de base favorito, porque muitos algoritmos o tratam como um valor excepcional. Em tais cenários, ele pode ser usado como um sinalizador para sinalizar que uma condição requer algum tratamento especial (como a configuração de um valor padrão).
Você pode atribuir Noneaos argumentos de palavra-chave de uma função e testá-la explicitamente.
def my_function(value, param=None):if param isNone:# do something outrageous!
Você pode retorná-lo como padrão ao tentar acessar o atributo de um objeto e testá-lo explicitamente antes de fazer algo especial.
value = getattr(some_obj,'some_attribute',None)if value isNone:# do something spectacular!
Por padrão, o get()método de um dicionário retorna Noneao tentar acessar uma chave inexistente:
>>> some_dict ={}>>> value = some_dict.get('foo')>>> value isNoneTrue
Se você tentar acessá-lo usando a notação subscrita, um KeyErrorserá gerado
>>> value = some_dict['foo']KeyError:'foo'
Da mesma forma, se você tentar exibir um item não existente
>>> value = some_dict.pop('foo')KeyError:'foo'
que você pode suprimir com um valor padrão que geralmente é definido como None
value = some_dict.pop('foo',None)if value isNone:# booom!
None usado como sinalizador e valor válido
Os usos descritos acima de Noneaplicar quando não é considerado um valor válido, mas mais como um sinal para fazer algo especial. No entanto, há situações em que às vezes é importante saber de onde Noneveio, porque, embora seja usado como sinal, também pode fazer parte dos dados.
Quando você consulta um objeto em busca de seu atributo, getattr(some_obj, 'attribute_name', None)retornando None, não informa se o atributo que você estava tentando acessar foi definido Noneou se estava totalmente ausente do objeto. A mesma situação ao acessar uma chave de um dicionário como some_dict.get('some_key'), você não sabe se some_dict['some_key']está faltando ou se está apenas definido como None. Se você precisar dessas informações, a maneira usual de lidar com isso é tentar acessar diretamente o atributo ou a chave de dentro de uma try/exceptconstrução:
try:# equivalent to getattr() without specifying a default# value = getattr(some_obj, 'some_attribute')
value = some_obj.some_attribute
# now you handle `None` the data hereif value isNone:# do something here because the attribute was set to NoneexceptAttributeError:# we're now hanling the exceptional situation from here.# We could assign None as a default value if required.
value =None# In addition, since we now know that some_obj doesn't have the# attribute 'some_attribute' we could do something about that.
log_something(some_obj)
Da mesma forma com dict:
try:
value = some_dict['some_key']if value isNone:# do something here because 'some_key' is set to NoneexceptKeyError:# set a default
value =None# and do something because 'some_key' was missing# from the dict.
log_something(some_dict)
Os dois exemplos acima mostram como lidar com casos de objetos e dicionários, e as funções? A mesma coisa, mas usamos o argumento de palavra-chave double asteriscos para esse fim:
def my_function(**kwargs):try:
value = kwargs['some_key']if value isNone:# do something because 'some_key' is explicitly # set to NoneexceptKeyError:# we assign the default
value =None# and since it's not coming from the caller.
log_something('did not receive "some_key"')
None usado apenas como um valor válido
Se você achar que seu código está repleto de try/exceptpadrões acima, simplesmente para diferenciar Nonesinalizadores e Nonedados, basta usar outro valor de teste. Há um padrão em que um valor que fica fora do conjunto de valores válidos é inserido como parte dos dados em uma estrutura de dados e é usado para controlar e testar condições especiais (por exemplo, limites, estado, etc.). Esse valor é chamado de sentinela e pode ser usado da maneira que Noneé usado como sinal. É trivial criar um sentinela em Python.
undefined = object()
O undefinedobjeto acima é único e não faz muito de nada que possa interessar a um programa; portanto, é um excelente substituto para Nonecomo sinalizador. Algumas advertências se aplicam, mais sobre isso após o código.
Com função
def my_function(value, param1=undefined, param2=undefined):if param1 is undefined:# we know nothing was passed to it, not even None
log_something('param1 was missing')
param1 =Noneif param2 is undefined:# we got nothing here either
log_something('param2 was missing')
param2 =None
Com ditado
value = some_dict.get('some_key', undefined)if value isNone:
log_something("'some_key' was set to None")if value is undefined:# we know that the dict didn't have 'some_key'
log_something("'some_key' was not set at all")
value =None
Com um objeto
value = getattr(obj,'some_attribute', undefined)if value isNone:
log_something("'obj.some_attribute' was set to None")if value is undefined:# we know that there's no obj.some_attribute
log_something("no 'some_attribute' set on obj")
value =None
Como mencionei anteriormente, as sentinelas personalizadas vêm com algumas ressalvas. Primeiro, não são palavras-chave None, portanto, o python não as protege. Você pode substituir os itens undefinedacima a qualquer momento, em qualquer lugar do módulo definido, portanto, tenha cuidado com a exposição e uso deles. Em seguida, a instância retornada por object()não é um singleton, se você fizer essa chamada 10 vezes, obterá 10 objetos diferentes. Finalmente, o uso de um sentinela é altamente idiossincrático. Um sentinela é específico da biblioteca em que é usado e, portanto, seu escopo geralmente deve ser limitado aos internos da biblioteca. Não deve "vazar". O código externo só deve ficar ciente disso, se seu objetivo é estender ou suplementar a API da biblioteca.
Ah, então IIUC que normalmente ainda vai acabar chamando coisa .__ eq__? Nesse caso, retiro minha sugestão.
HkBst 02/11/19
@MichaelEkoka, você pode compartilhar a fonte dessas informações impressionantes e úteis.
Anidhya Bhatnagar
Prática padrão. Você pode encontrar algumas dicas sobre isso no tutorial em Python , mas ler o código-fonte de projetos populares é o meu conselho número um para mergulhar rapidamente no Python idiomático .
Michael Ekoka
67
Não é chamado nulo como em outros idiomas, mas None. Sempre há apenas uma instância desse objeto, portanto, você pode verificar a equivalência com x is None(comparação de identidade) em vez de x == None, se desejar.
Vou encontrar uma maneira de quebrar o Python re-instanciando None. Então todas aquelas pessoas inteligentes que compararam NoneTypetriunfarão!
Zenexer
28
No Python, para representar a ausência de um valor, você pode usar o valor Nenhum ( types.NoneType.None ) para objetos e "" (ou len () == 0 ) para seqüências de caracteres. Portanto:
if yourObject isNone:# if yourObject == None:...if yourString =="":# if yourString.len() == 0:...
Com relação à diferença entre "==" e "is", o teste da identidade do objeto usando "==" deve ser suficiente. No entanto, como a operação "is" é definida como a operação de identidade do objeto, provavelmente é mais correto usá-la, em vez de "==". Não tenho certeza se existe mesmo uma diferença de velocidade.
De qualquer forma, você pode dar uma olhada em:
Página do documento Constantes internas do Python .
Tanto quanto eu sei, (0 == false) retorna true EM CADA linguagem de programação. Isso ocorre porque false é codificado como 0 e "true" como tudo que NÃO é 0. No entanto, não se esqueça de que o operador "is" não é o mesmo do "==". Essa é mais ou menos a mesma diferença entre "==" e "igual" em Java. O operador "is", na verdade, verifica se DOIS OBJETOS são iguais (a mesma instância e NÃO o mesmo conteúdo)!
Paolo Rovelli
12
Paolo, FYI, (0 == false) não retorna true em todas as linguagens de programação. Um exemplo de contador rápido seria Scala, em que (0 == false) retorna false, e tenho certeza de que Scala não é a única linguagem de programação que retorna false ao comparar um número com um booleano.
22430 Rob Wilton
2
OK, entendi! Então, digamos na maioria das linguagens de programação.
Paolo Rovelli 28/08
3
Em JavaScript, a razão 0 == falseretorna trueé porque o double-iguala operador faz Tipo de coerção. Com o operador triple-equal, no entanto, 0 === falseretorna false, porque 'number' e 'boolean' são tipos diferentes.
Jkdev 18/05
1
@PaoloRovelli, em Lua, Ruby e Clojure, 0 é tratado como trueem condicionais. Em Rust and Go, 0e false diferentes tipos que não podem ser comparados para igualdade.
scooter-dangle
0
Nulo é um tipo de objeto especial como:
>>>type(None)<class'NoneType'>
Você pode verificar se um objeto está na classe 'NoneType':
Não, não vai. Essa expressão retornará Truepara qualquer valor falso, não apenas None.
insert_name_here
Verdadeiro, e o simples "se não for foo:" não responderia corretamente à pergunta original, como afirmado. No entanto, o python é digitado dinamicamente e convida a reduzir protocolos de sintaxe, portanto, para mim parece válido considerar construções mais simples e similares.
egg is None
sobreegg == None
: O último pode ser sobrecarregado, e é provável que quebrar quando comparando objeto válido com Nenhum (depende de como ele é implementado, mas você não espera que todos a tomar comparações com None em conta, não é?) , enquantois
sempre funciona da mesma maneira.None
Nulo do Python?Não existe
null
no Python, mas simNone
. Como já foi dito, a maneira mais precisa de testar se algo foi dadoNone
como valor é usar ois
operador de identidade, que testa se duas variáveis se referem ao mesmo objeto.O básico
Existe e só pode haver um
None
None
é a única instância da classeNoneType
e qualquer tentativa adicional de instanciar essa classe retornará o mesmo objeto, o que criaNone
um singleton. Os recém-chegados ao Python costumam ver mensagens de erro que mencionamNoneType
e se perguntam o que é. É minha opinião pessoal que essas mensagens poderiam simplesmente ser mencionadasNone
pelo nome porque, como veremos em breve,None
deixa pouco espaço para a ambiguidade. Portanto, se você vir algumaTypeError
mensagem que mencione queNoneType
não pode ou não pode fazer isso, saiba que é simplesmente aquelaNone
que estava sendo usada de uma maneira que não pode.Além disso,
None
é uma constante interna, assim que você inicia o Python, ele está disponível para uso em qualquer lugar, seja no módulo, na classe ou na função.NoneType
por outro lado, não, você precisa obter uma referência a ele primeiro consultandoNone
sua classe.Você pode verificar
None
a singularidade da função de identidade do Pythonid()
. Retorna o número único atribuído a um objeto, cada objeto possui um. Se o id de duas variáveis for o mesmo, elas apontam de fato para o mesmo objeto.None
não pode ser substituídoEm uma versão muito mais antiga do Python (anterior à 2.4), era possível reatribuir
None
, mas não mais. Nem mesmo como um atributo de classe ou nos limites de uma função.Portanto, é seguro assumir que todas as
None
referências são iguais. Não há "costume"None
.Para testar o
None
uso dois
operadorAo escrever o código, você pode tentar testar o Noneness dessa maneira:
Ou para testar falsidade como esta
Você precisa entender as implicações e por que geralmente é uma boa idéia ser explícito.
Caso 1: testando se um valor é
None
por que fazer isso
ao invés de
O primeiro é equivalente a:
Considerando que a expressão
value==None
é de fato aplicada assimse o valor realmente for
None
, você obterá o que esperava.Na maioria dos casos comuns, o resultado será o mesmo, mas o
__eq__()
método abre uma porta que anula qualquer garantia de precisão, pois pode ser substituída em uma classe para fornecer um comportamento especial.Considere esta classe.
Então você experimenta
None
e funcionaMas também funciona na string vazia
E ainda
Caso 2: usando
None
como um booleanoOs dois testes a seguir
são de fato avaliados como
None
é um "falsey", significando que, se convertido em um booleano, ele retornaráFalse
e, se aplicado, onot
operador retornaráTrue
. Observe, no entanto, que não é uma propriedade exclusivaNone
. Além deFalse
si mesma, a propriedade é compartilhada por listas vazias, tuplas, conjuntos, dictos, seqüências de caracteres, além de 0 e todos os objetos de classes que implementam o__bool__()
método mágico para retornarFalse
.Portanto, ao testar variáveis da seguinte maneira, fique atento ao que você está incluindo ou excluindo do teste:
Acima, você quis chamar
init_value()
quando o valor está definido especificamente paraNone
, ou você quis dizer que um valor definido como0
, ou a sequência vazia ou uma lista vazia também deveria acionar a inicialização. Como eu disse, fique atento. Como geralmente é o caso explícito em Python, é melhor que implícito .None
na práticaNone
usado como um valor de sinalNone
tem um status especial em Python. É um valor de linha de base favorito, porque muitos algoritmos o tratam como um valor excepcional. Em tais cenários, ele pode ser usado como um sinalizador para sinalizar que uma condição requer algum tratamento especial (como a configuração de um valor padrão).Você pode atribuir
None
aos argumentos de palavra-chave de uma função e testá-la explicitamente.Você pode retorná-lo como padrão ao tentar acessar o atributo de um objeto e testá-lo explicitamente antes de fazer algo especial.
Por padrão, o
get()
método de um dicionário retornaNone
ao tentar acessar uma chave inexistente:Se você tentar acessá-lo usando a notação subscrita, um
KeyError
será geradoDa mesma forma, se você tentar exibir um item não existente
que você pode suprimir com um valor padrão que geralmente é definido como
None
None
usado como sinalizador e valor válidoOs usos descritos acima de
None
aplicar quando não é considerado um valor válido, mas mais como um sinal para fazer algo especial. No entanto, há situações em que às vezes é importante saber de ondeNone
veio, porque, embora seja usado como sinal, também pode fazer parte dos dados.Quando você consulta um objeto em busca de seu atributo,
getattr(some_obj, 'attribute_name', None)
retornandoNone
, não informa se o atributo que você estava tentando acessar foi definidoNone
ou se estava totalmente ausente do objeto. A mesma situação ao acessar uma chave de um dicionário comosome_dict.get('some_key')
, você não sabe sesome_dict['some_key']
está faltando ou se está apenas definido comoNone
. Se você precisar dessas informações, a maneira usual de lidar com isso é tentar acessar diretamente o atributo ou a chave de dentro de umatry/except
construção:Da mesma forma com dict:
Os dois exemplos acima mostram como lidar com casos de objetos e dicionários, e as funções? A mesma coisa, mas usamos o argumento de palavra-chave double asteriscos para esse fim:
None
usado apenas como um valor válidoSe você achar que seu código está repleto de
try/except
padrões acima, simplesmente para diferenciarNone
sinalizadores eNone
dados, basta usar outro valor de teste. Há um padrão em que um valor que fica fora do conjunto de valores válidos é inserido como parte dos dados em uma estrutura de dados e é usado para controlar e testar condições especiais (por exemplo, limites, estado, etc.). Esse valor é chamado de sentinela e pode ser usado da maneira queNone
é usado como sinal. É trivial criar um sentinela em Python.O
undefined
objeto acima é único e não faz muito de nada que possa interessar a um programa; portanto, é um excelente substituto paraNone
como sinalizador. Algumas advertências se aplicam, mais sobre isso após o código.Com função
Com ditado
Com um objeto
Como mencionei anteriormente, as sentinelas personalizadas vêm com algumas ressalvas. Primeiro, não são palavras-chave
None
, portanto, o python não as protege. Você pode substituir os itensundefined
acima a qualquer momento, em qualquer lugar do módulo definido, portanto, tenha cuidado com a exposição e uso deles. Em seguida, a instância retornada porobject()
não é um singleton, se você fizer essa chamada 10 vezes, obterá 10 objetos diferentes. Finalmente, o uso de um sentinela é altamente idiossincrático. Um sentinela é específico da biblioteca em que é usado e, portanto, seu escopo geralmente deve ser limitado aos internos da biblioteca. Não deve "vazar". O código externo só deve ficar ciente disso, se seu objetivo é estender ou suplementar a API da biblioteca.fonte
Não é chamado nulo como em outros idiomas, mas
None
. Sempre há apenas uma instância desse objeto, portanto, você pode verificar a equivalência comx is None
(comparação de identidade) em vez dex == None
, se desejar.fonte
None
. Então todas aquelas pessoas inteligentes que compararamNoneType
triunfarão!No Python, para representar a ausência de um valor, você pode usar o valor Nenhum ( types.NoneType.None ) para objetos e "" (ou len () == 0 ) para seqüências de caracteres. Portanto:
Com relação à diferença entre "==" e "is", o teste da identidade do objeto usando "==" deve ser suficiente. No entanto, como a operação "is" é definida como a operação de identidade do objeto, provavelmente é mais correto usá-la, em vez de "==". Não tenho certeza se existe mesmo uma diferença de velocidade.
De qualquer forma, você pode dar uma olhada em:
fonte
0 == false
retornatrue
é porque o double-iguala operador faz Tipo de coerção. Com o operador triple-equal, no entanto,0 === false
retornafalse
, porque 'number' e 'boolean' são tipos diferentes.true
em condicionais. Em Rust and Go,0
efalse
diferentes tipos que não podem ser comparados para igualdade.Nulo é um tipo de objeto especial como:
Você pode verificar se um objeto está na classe 'NoneType':
Mais informações estão disponíveis no Python Docs
fonte
Por teste de valor de Verdade , 'None' testa diretamente como FALSE, portanto a expressão mais simples será suficiente:
fonte
True
para qualquer valor falso, não apenasNone
.