O que TypeError: 'NoneType' object is not iterable
significa error ?
Estou recebendo este código Python:
def write_file(data, filename): # creates file and writes list to it
with open(filename, 'wb') as outfile:
writer = csv.writer(outfile)
for row in data: # ABOVE ERROR IS THROWN HERE
writer.writerow(row)
None
é coagido como uma sequência, deve produzir uma sequência vazia, totalmente inofensiva.None
nunca é coagido a nada . Ter umNone
comportamento silencioso como outros tipos oculta erros; isso é o oposto de "inofensivo". Se você precisar de um espaço reservado falso para a sequência vazia, poderá usar()
ou''
/""
, os quais são singletons e podem ser carregados o mais barato possívelNone
. Se você deseja optar por tratar silenciosamente qualquer coisa falsa como uma sequência vazia, pode fazê-lofor row in data or ():
, mas ninguém faz isso, porque passarNone
para uma função que espera uma sequência é um erro que não deve passar silenciosamente.Respostas:
Isso significa que o valor de
data
éNone
.fonte
for
loop em vez de gerar uma exceção. O design do Python é falho aqui. QuandoNone
é tratado como iterável, ele deve retornar pelo menos a lista vazia. Essa exceção nunca ajudou ninguém na vida real a não ser nos fazer inserir algunsif data is not None:
tipos feios de manuseio.fieldlist
forDictWriter
forNone
!for i in data or []
data
existe ou nãoNone
, mas permitir que a exceção ocorra. Você deseja que os consumidores da sua API saibam quando a usaram incorretamente. AceitarNone
como uma sequência vazia deixaria erros comomylist = mylist.extend(morestuff)
, conseguir se esconder ainda mais; eles acham queextend
editaram umlist
(e o fizeram, mas o substituíram imediatamente porNone
), depois o passam para a função do OP e se perguntam por que o arquivo está vazio, sem erros de qualquer tipo.Explicação do erro: O objeto 'NoneType' não é iterável
Em python2, NoneType é o tipo de None. No Python3, NoneType é a classe None, por exemplo:
A iteração sobre uma variável com valor Nenhum falha:
Os métodos Python retornam NoneType se eles não retornam um valor:
Você precisa verificar suas construções de loop para NoneType assim:
Guido diz que apenas use
is
para verificarNone
porqueis
é mais robusto para verificação de identidade. Não use operações de igualdade porque elas podem cuspir implementações próprias. Diretrizes de estilo de codificação do Python - PEP-008Os tipos são furtivos e podem se infiltrar a partir de lambdas:
NoneType não é uma palavra-chave válida:
Concatenação de
None
e uma string:O que está acontecendo aqui?
O intérprete do Python converteu seu código em bycode pyc. A máquina virtual Python processou o bytecode, encontrou uma construção em loop que dizia iterar sobre uma variável que continha None. A operação foi realizada invocando o
__iter__
método no None.Nenhum possui um
__iter__
método definido, portanto, a máquina virtual do Python diz o que vê: que o NoneType não tem__iter__
método.É por isso que a ideologia de digitação de pato do Python é considerada ruim. O programador faz algo completamente razoável com uma variável e, em tempo de execução, é contaminado por None, a máquina virtual python tenta resistir e solta um monte de besteiras não relacionadas por todo o tapete.
Java ou C ++ não tem esses problemas porque esse programa não poderia ser compilado, pois você não definiu o que fazer quando nenhum ocorrer. O Python dá ao programador muita corda para se enforcar, permitindo que você faça muitas coisas que não se espera que funcionem em circunstâncias excepcionais. O Python é um sim-homem, dizendo sim-senhor quando o impede de se prejudicar, como Java e C ++ fazem.
fonte
NoneType
eNone
(b) pensa queNameError: name 'NoneType' is not defined
eTypeError: cannot concatenate 'str' and 'NoneType' objects
são os mesmos queTypeError: 'NoneType' object is not iterable
(c) comparação entre Python e Java é "um monte de bobagens não relacionada"null
para uma função que espera qualquer tipo de coleção. C ++ teria o mesmo problema (mas geralmente apenas morre em um segfault sem relatar a causa) paranullptr
(reconhecidamente, um bom C ++ raramente usa ponteiros, mas o que você demonstrou é um Python ruim e um C ++ ruim também pode morrer em tempo de execução de nulos) . Python está fazendo a coisa correta aqui; não é "soldado", está errando no momento em que você tenta usarNone
para algoNone
que não pode fazer. Seu problema não é com o Python, é com linguagens tipadas dinamicamente em geral.Código:
for row in data:
Mensagem de erro:
TypeError: 'NoneType' object is not iterable
De que objeto está reclamando? Escolha de dois,
row
edata
. Emfor row in data
, o que precisa ser iterável? Sódata
.Qual é o problema
data
? Seu tipo éNoneType
. SóNone
tem tipoNoneType
. Entãodata is None
.Você pode verificar isso em um IDE ou inserindo, por exemplo,
print "data is", repr(data)
antes dafor
instrução e executando novamente.Pense no que você precisa fazer a seguir: como "nenhum dado" deve ser representado? Nós escrevemos um arquivo vazio? Criamos uma exceção ou registramos um aviso ou ficamos em silêncio?
fonte
Outra coisa que pode produzir esse erro é quando você está configurando algo igual ao retorno de uma função, mas esqueceu de realmente retornar qualquer coisa.
Exemplo:
Esse é um erro difícil de detectar, porque o erro também pode ser produzido se a variável de linha for None em uma das iterações. A maneira de detectar isso é que o rastreamento falha na última linha e não dentro da função.
Se você estiver retornando apenas uma variável de uma função, não tenho certeza se o erro seria produzido ... Suspeito que o erro "O objeto 'NoneType' não seja iterável no Python". Nesse caso, na verdade está implicando "Ei, estou tentando para iterar sobre os valores de retorno para atribuí-los a essas três variáveis em ordem, mas só estou obtendo Nenhum para iterar "
fonte
Isso significa que a variável de dados está passando None (que é do tipo NoneType), seu equivalente para nada . Portanto, não pode ser iterável como uma lista, como você está tentando fazer.
fonte
for row in data or []:
Você está chamando write_file com argumentos como este:
Mas você não definiu 'foo' corretamente ou possui um erro de digitação no código, para que ele crie uma nova variável vazia e a transmita.
fonte
Para mim, foi o caso de usar meu chapéu Groovy em vez do chapéu do Python 3.
Esqueceu a
return
palavra-chave no final de umadef
função.Não estava codificando Python 3 a sério há alguns meses. Estava pensando que a última declaração avaliada na rotina estava sendo retornada pela maneira Groovy.
Realizou algumas iterações, observando o rastreamento da pilha, inserindo a
try: ... except TypeError: ...
depuração de bloco / percorrendo o código para descobrir o que estava errado.A solução para a mensagem certamente não cometeu o erro.
fonte