TypeError: объект 'NoneType' не повторяется в Python

Что означает ошибка TypeError: 'NoneType' object is not iterable?

Я получаю это на этом коде 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)

person Alex Gordon    schedule 08.10.2010    source источник
comment
Это одно из моих досадных разочарований в Python. Когда None вводится как последовательность, он должен производить пустую последовательность, совершенно безвредную.   -  person nehem    schedule 01.09.2017
comment
@nehemiah: Python строго типизирован (только не статически типизирован). None никогда не принуждают к чему-либо. Если None молча ведет себя как другие типы, скрываются ошибки; это противоположность безобидному. Если вам нужен ложный заполнитель для пустой последовательности, вы можете использовать () или _4 _ / _ 5_, оба из которых являются одиночными и могут быть загружены так же дешево, как None. Если вы хотите разрешить молча обрабатывать любую ложную информацию как пустую последовательность, вы можете сделать for row in data or ():, но никто этого не сделает, потому что передача None функции, ожидающей последовательность, является ошибкой, которая не должна проходить молча.   -  person ShadowRanger    schedule 05.10.2018
comment
Вы также можете получить эту ошибку, когда в python 2 устанавливаете модуль, который больше не поддерживает python 2, например. stackoverflow.com/q/63346648/838494   -  person Albert Hendriks    schedule 01.01.2021
comment
@nehem Вы, должно быть, являетесь поклонником Javascript.   -  person Matt Yoon    schedule 20.07.2021
comment
@MattYoon JS многое понял правильно.   -  person nehem    schedule 20.07.2021
comment
@ShadowRanger - уродливое оправдание, если str можно с радостью рассматривать как итерацию, что не так в принуждении None быть пустым итерабельным, особенно там, где намерение ясно. Что еще хуже, списки и dict могут быть преобразованы в логические значения, даже строки тоже. Где здесь держится строго типизированный аргумент?   -  person nehem    schedule 20.07.2021


Ответы (8)


Это означает, что значение data равно None.

person vanza    schedule 08.10.2010
comment
Правильно, но автор общего сценария намеревался полностью пропустить цикл for вместо того, чтобы вызывать исключение. Дизайн Python здесь ошибочен. Когда None рассматривается как итеративный, он должен возвращать по крайней мере пустой список. Это исключение никогда никому не помогло в реальной жизни, кроме как заставило нас добавить несколько уродливых if data is not None: способов обработки. - person nehem; 01.09.2017
comment
Для более конкретного ответа, это может произойти, если fieldlist для DictWriter будет None! - person Arklur; 08.12.2017
comment
Попробуйте for i in data or [] - person BMW; 28.03.2018
comment
@nehemiah: На самом деле, правильный подход - не проверять, является ли data или нет None, а разрешать возникновение исключения. Вы хотите, чтобы потребители вашего API знали, когда они использовали его неправильно. Принятие None как пустой последовательности позволило бы таким ошибкам, как mylist = mylist.extend(morestuff), скрываться еще дольше; они думают, что extend записали list (и они это сделали, но тут же заменили его на None), затем передают его функции OP и задаются вопросом, почему файл пуст, без каких-либо ошибок. - person ShadowRanger; 05.10.2018

Объяснение ошибки: объект 'NoneType' не повторяется

В python2 NoneType является типом None. В Python3 NoneType - это класс None, например:

>>> 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.

Итерация по переменной, имеющей значение None, не выполняется:

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

Методы Python возвращают NoneType, если они не возвращают значение:

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

Вам нужно проверить свои конструкции цикла на предмет NoneType следующим образом:

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

Гвидо говорит, что используйте is только для проверки None, потому что is более устойчив к проверке личности. Не используйте операции равенства, потому что они сами могут выплюнуть пузырьки реализации. Рекомендации по стилю кодирования Python - PEP-008

Типы NoneTypes являются скрытными и могут проникать через лямбды:

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

NoneType не является допустимым ключевым словом:

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

Объединение None и строки:

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

Что тут происходит?

Интерпретатор Python преобразовал ваш код в байт-код pyc. Виртуальная машина Python обработала байт-код и обнаружила циклическую конструкцию, которая выполняет итерацию по переменной, содержащей None. Операция была выполнена путем вызова метода __iter__ для объекта None.

Ни один из них не имеет __iter__ определенного метода, поэтому виртуальная машина Python сообщает вам, что видит: этот NoneType не имеет __iter__ метода.

Вот почему идеология Python "утка" считается плохой. Программист делает что-то вполне разумное с переменной, и во время выполнения она заражается None, виртуальная машина python пытается атаковать и изводит кучу несвязанной чепухи по всему ковру.

Java или C ++ не имеют этих проблем, потому что такой программе нельзя будет компилировать, поскольку вы не определили, что делать, когда возникает None. Python дает программисту массу возможностей повеситься, позволяя делать множество вещей, от которых нельзя ожидать, что они сработают в исключительных обстоятельствах. Python - согласный человек, говоря «да-сэр», когда он пытается помешать вам навредить себе, как это делают Java и C ++.

person Eric Leschinski    schedule 07.07.2015
comment
(а) Смущает NoneType и None (б) думает, что NameError: name 'NoneType' is not defined и TypeError: cannot concatenate 'str' and 'NoneType' objects такие же, как TypeError: 'NoneType' object is not iterable (в) сравнение между Python и java - это куча несвязанной чепухи - person John Machin; 08.01.2017
comment
Умм ... У Java были бы практически идентичные проблемы, если бы вы передали null функции, ожидающей любого типа коллекции. У C ++ была бы такая же проблема (но обычно просто умирает в segfault, не сообщая о причине) для nullptr (надо признать, хороший C ++ редко использует указатели, но то, что вы продемонстрировали, является плохим Python, а плохой C ++ может умереть во время выполнения и от нулей ). Python здесь делает правильные вещи; он не работает, он выдает ошибку в тот момент, когда вы пытаетесь использовать None для того, чего None не может сделать. Ваша проблема не в Python, а в языках с динамической типизацией в целом. - person ShadowRanger; 05.10.2018

Код: for row in data:
Сообщение об ошибке: TypeError: 'NoneType' object is not iterable

На какой объект жалуется? На выбор два: row и data. Что в for row in data должно быть повторяемым? Только data.

В чем проблема с data? Его тип NoneType. Только None имеет тип NoneType. Итак data is None.

Вы можете проверить это в IDE или вставив, например, print "data is", repr(data) перед оператором for и запускается повторно.

Подумайте, что вам нужно сделать дальше: Как следует представить «без данных»? Мы пишем пустой файл? Мы вызываем исключение, регистрируем предупреждение или молчим?

person John Machin    schedule 08.10.2010

Еще одна вещь, которая может вызвать эту ошибку, - это когда вы устанавливаете что-то, равное возврату из функции, но фактически забыли вернуть что-либо.

Пример:

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)

Это немного сложная ошибка для обнаружения, потому что ошибка также может возникнуть, если переменная строки окажется равной None на одной из итераций. Способ определить это заключается в том, что трассировка не выполняется на последней строке, а не внутри функции.

Если вы возвращаете только одну переменную из функции, я не уверен, возникнет ли ошибка ... Я подозреваю, что ошибка «объект 'NoneType' не повторяется в Python» в этом случае на самом деле подразумевает: «Эй, я пытаюсь чтобы перебрать возвращаемые значения, чтобы присвоить их этим трем переменным по порядку, но я получаю только None для перебора "

person gunslingor    schedule 25.01.2017
comment
Именно это привело меня сюда. Итак, каково же решение Pythonic для такой ситуации? - person Dr_Zaszuś; 05.10.2018
comment
Похоже, здесь есть некоторая помощь: stackoverflow.com/questions/1274875/ - person Dr_Zaszuś; 05.10.2018
comment
Dr_Zaszus, это как раз и мой вопрос. Этот конкретный ответ лишь говорит о том, что проблема действительно существует. И принятый ответ в основном также просто говорит «да», это вызовет ошибку. Вся цепочка лишена реальных, хороших, общепринятых ответов для решения основной проблемы. Лучшее решение, упомянутое в комментарии, заключается в добавлении, если data не None :, что является уродливым решением. - person user3685427; 24.03.2021

Это означает, что переменная данных передает None (это тип NoneType), его эквивалент для ничего. Таким образом, он не может быть повторен как список, как вы пытаетесь это сделать.

person Rod    schedule 08.10.2010
comment
было бы неплохо, если бы просто повторять как пустой список ... это накаляло бы более чистый код и меньше проверки ошибок - person deltanine; 19.08.2013
comment
@deltanine Я думаю, это усложнило бы обнаружение множества проблем. Я рад, что None не отличается от пустого итеративного объекта. Если вам нужно описанное вами поведение, просто используйте for row in data or []: - person Mark; 27.12.2014
comment
@Mark намного чище, если он возвращает пустой список. Если вы хотите, чтобы это не удалось, вы всегда можете добавить строку if data is None: raise - person nehem; 20.07.2021

Вы вызываете write_file с такими аргументами:

write_file(foo, bar)

Но вы неправильно определили 'foo' или в вашем коде есть опечатка, поэтому он создает новую пустую переменную и передает ее.

person clee    schedule 08.10.2010

Для меня это был случай моей классной шляпы вместо Python 3.

Забыли ключевое слово return в конце def функции.

Не занимался программированием Python 3 всерьез пару месяцев. Думал, что последний оператор, оцененный в рутине, возвращался способом Groovy (или Rust).

Потребовалось несколько итераций, просмотр трассировки стека, вставка try: ... except TypeError: ... блока отладки / пошагового выполнения кода, чтобы выяснить, что не так.

Решение для сообщения, конечно же, не заставило меня выскочить на ошибку.

person JGFMK    schedule 27.11.2018

Просто продолжите цикл, когда вы получите None Exception,

пример:

   a = None
   if a is None:
       continue
   else:
       print("do something")

Это может быть любая итерация из БД или файла Excel.

person Sappaa    schedule 21.01.2021