TypeError: el objeto 'NoneType' no es iterable en Python


145

Que significa error TypeError: 'NoneType' object is not iterable ?

Lo estoy obteniendo en este código de 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)

Esta es una de mis decepciones molestas en Python. Cuando Nonese coacciona como secuencia, debe producir una secuencia vacía, totalmente inofensiva.
nehem

77
@nehemiah: Python está fuertemente tipado (simplemente no estáticamente tipado). Nonenunca es forzado a nada . Tener un Nonecomportamiento silencioso como otros tipos oculta errores; eso es lo contrario de "inofensivo". Si necesita un marcador de posición falso para la secuencia vacía, puede usar ()o ''/ "", los cuales son singletons y se pueden cargar tan barato como sea posible None. Si desea optar por tratar silenciosamente cualquier cosa falsa como una secuencia vacía, puede hacerlo for row in data or ():, pero nadie lo hace, porque pasar Nonea una función que espera una secuencia es un error que no debe pasar en silencio.
ShadowRanger

Respuestas:


203

Significa el valor de dataes None.


37
Correcto, pero el autor del escenario común que se pretende aquí es omitir totalmente el forbucle en lugar de generar una excepción. El diseño de Python es defectuoso aquí. Cuando Nonese trata como iterable, debe devolver al menos una lista vacía. Esta excepción nunca ayudó a nadie en la vida real, aparte de hacernos insertar un if data is not None:tipo de manejo feo .
nehem

Para una respuesta más concreta, puede suceder si el fieldlistpara el DictWriteres None!
Arklur

30
Pruebafor i in data or []
BMW

44
@nehemiah: En realidad, el enfoque correcto no es verificar si dataes o no None, sino dejar que ocurra la excepción. Usted quiere los consumidores de su API para saber cuando se ha usado de manera incorrecta. Aceptar Nonecomo una secuencia vacía permitiría que errores como mylist = mylist.extend(morestuff), logren esconderse aún más; piensan que editaron extendun list(y lo hicieron, pero luego lo reemplazaron de inmediato None), luego lo pasaron a la función del OP y se preguntan por qué el archivo está vacío, sin que se generen errores de ningún tipo.
ShadowRanger

83

Explicación del error: el objeto 'NoneType' no es iterable

En python2, NoneType es el tipo de Ninguno. En Python3 NoneType es la clase de Ninguno, por ejemplo:

>>> print(type(None))     #Python2
<type 'NoneType'>         #In Python2 the type of None is the 'NoneType' type.

>>> print(type(None))     #Python3
<class 'NoneType'>        #In Python3, the type of None is the 'NoneType' class.

Iterar sobre una variable que tiene valor Ninguno falla:

for a in None:
    print("k")     #TypeError: 'NoneType' object is not iterable

Los métodos de Python devuelven NoneType si no devuelven un valor:

def foo():
    print("k")
a, b = foo()      #TypeError: 'NoneType' object is not iterable

Debe verificar sus construcciones de bucle para NoneType como este:

a = None 
print(a is None)              #prints True
print(a is not None)          #prints False
print(a == None)              #prints True
print(a != None)              #prints False
print(isinstance(a, object))  #prints True
print(isinstance(a, str))     #prints False

Guido dice que solo se usa ispara verificar Noneporque ises más robusto para la verificación de identidad. No use operaciones de igualdad porque pueden escupir su propia implementación de burbujas. Pautas de estilo de codificación de Python - PEP-008

NoneTypes son furtivos y pueden colarse de lambdas:

import sys
b = lambda x : sys.stdout.write("k") 
for a in b(10): 
    pass            #TypeError: 'NoneType' object is not iterable 

NoneType no es una palabra clave válida:

a = NoneType     #NameError: name 'NoneType' is not defined

Concatenación de Noney una cadena:

bar = "something"
foo = None
print foo + bar    #TypeError: cannot concatenate 'str' and 'NoneType' objects

¿Que está pasando aqui?

El intérprete de Python convirtió su código a pyc bytecode. La máquina virtual de Python procesó el código de bytes, encontró una construcción en bucle que dijo iterar sobre una variable que contenía None. La operación se realizó invocando el__iter__ método en Ninguno.

Ninguno no tiene un __iter__método definido, por lo que la máquina virtual de Python le dice lo que ve: que NoneType no tiene__iter__ método.

Esta es la razón por la mecanografía de pato de Python ideología de se considera mala. El programador hace algo completamente razonable con una variable y en el tiempo de ejecución se contamina con None, la máquina virtual de Python intenta continuar, y vomita un montón de tonterías no relacionadas por toda la alfombra.

Java o C ++ no tienen estos problemas porque no se permitiría compilar un programa de este tipo, ya que no ha definido qué hacer cuando ocurre Ninguno. Python le da al programador mucha soga para ahorcarse permitiéndole hacer muchas cosas que no se debe esperar que funcionen en circunstancias excepcionales. Python es un sí, dice sí, señor, cuando te impide detenerte, como lo hacen Java y C ++.


2
(a) Confunde NoneTypey None(b) piensa que NameError: name 'NoneType' is not definedy TypeError: cannot concatenate 'str' and 'NoneType' objectsson lo mismo que TypeError: 'NoneType' object is not iterable(c) la comparación entre Python y Java es "un montón de tonterías no relacionadas"
John Machin

3
Umm ... Java tendría problemas esencialmente idénticos si pasaras nulla una función esperando cualquier tipo de colección. C ++ tendría el mismo problema (pero en general solo moriría en una falla por defecto sin informar la causa) para nullptr(es cierto que C ++ bueno rara vez usa punteros, pero lo que ha demostrado es Python malo, y C ++ malo también puede morir en tiempo de ejecución por nulos) . Python está haciendo lo correcto aquí; no es "seguir adelante", está fallando en el momento en que intentas usar Nonepara algo Noneque no puedes hacer. Su problema no es con Python, es con lenguajes dinámicamente escritos en general.
ShadowRanger

63

Código: for row in data:
Mensaje de error:TypeError: 'NoneType' object is not iterable

¿De qué objeto se queja? Elección de dos, rowy data. En for row in data, ¿cuál debe ser iterable? Solamentedata .

¿Cuál es el problema con data? Su tipo es NoneType. Solo Nonetiene tipo NoneType. Entoncesdata is None .

Puede verificar esto en un IDE, o insertando, por ejemplo, print "data is", repr(data)antes de la fordeclaración, y volviendo a ejecutar.

Piense en lo que debe hacer a continuación: ¿Cómo se debe representar "sin datos"? ¿Escribimos un archivo vacío? ¿Presentamos una excepción o registramos una advertencia o nos quedamos en silencio?


18

Otra cosa que puede producir este error es cuando está configurando algo igual al retorno de una función, pero se olvidó de devolver cualquier cosa.

Ejemplo:

def foo(dict_of_dicts):
    for key, row in dict_of_dicts.items():
        for key, inner_row in row.items():
            Do SomeThing
    #Whoops, forgot to return all my stuff

return1, return2, return3 = foo(dict_of_dicts)

Este es un error un poco difícil de detectar porque el error también se puede producir si la variable de fila es Ninguno en una de las iteraciones. La forma de detectarlo es que la traza falla en la última línea y no dentro de la función.

Si solo devuelve una variable de una función, no estoy seguro de si se producirá el error ... Sospecho que el error "El objeto 'NoneType' no es iterable en Python" en este caso en realidad implica "Hey, estoy intentando iterar sobre los valores de retorno para asignarlos a estas tres variables en orden, pero solo obtengo None para iterar "


1
Esto es exactamente lo que me trajo aquí. Entonces, ¿cuál es la solución pitónica para tal situación?
Dr_Zaszuś

1
Parece que hay algo de ayuda aquí: stackoverflow.com/questions/1274875/…
Dr_Zaszuś

8

Significa que la variable de datos está pasando None (que es type NoneType), su equivalente para nada . Por lo tanto, no puede ser iterable como una lista, como está tratando de hacer.


1
Sería bueno si solo iterara como una lista vacía ... sería un código más limpio y menos comprobación de errores
deltanine

44
@deltanine Creo que sería más difícil detectar muchos problemas. Me alegro de que None sea diferente de un iterable vacío. Si desea su comportamiento descrito, solo usefor row in data or []:
Mark

7

Estás llamando a write_file con argumentos como este:

write_file(foo, bar)

Pero no ha definido 'foo' correctamente, o tiene un error tipográfico en su código para que esté creando una nueva variable vacía y pasándola.


1

Para mí fue un caso de tener mi sombrero Groovy puesto en lugar del Python 3.

Olvidé la returnpalabra clave al final de una deffunción.

No había estado codificando Python 3 en serio durante un par de meses. Estaba pensando que la última declaración evaluada en la rutina se devolvía de la manera Groovy.

Tomó algunas iteraciones, observando el seguimiento de la pila, insertando la try: ... except TypeError: ...depuración de bloque / paso a través del código para descubrir qué estaba mal.

La solución para el mensaje ciertamente no hizo que el error saltara sobre mí.


Gracias. Este fue exactamente mi problema. Estaba a punto de volverme loco ...
J. Brett Cunningham
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.