TypeError:'NoneType'对象在Python中不可迭代

l--*_*''' 127 python nonetype

错误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)
Run Code Online (Sandbox Code Playgroud)

van*_*nza 179

这意味着"数据"是无.

  • 正确,但是作者在这里的常见场景完全是跳过`for`循环而不是引发异常.Python的设计在这里存在缺陷.当`None`被视为可迭代时,它必须至少返回空列表.这个例外从来没有帮助现实生活中的任何人,除了让我们插入一些丑陋的`如果数据不是None:`那种处理. (27认同)
  • 尝试`for i in data或[]` (20认同)
  • @nehemiah:实际上,正确的方法不是检查data是否为None,而是让异常发生。您*希望* API的使用者知道他们何时不正确地使用它。将`None`接受为空序列会使`mylist = mylist.extend(morestuff)`之类的错误隐藏更长的时间。他们认为他们“扩展了”一个“清单”(他们这样做了,但随后立即将其替换为“无”),然后将其传递给OP的功能,想知道为什么文件为空,没有任何类型的错误。 (3认同)

Eri*_*ski 66

错误说明:'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.
Run Code Online (Sandbox Code Playgroud)

迭代具有值None的变量失败:

for a in None:
    print("k")     #TypeError: 'NoneType' object is not iterable
Run Code Online (Sandbox Code Playgroud)

如果Python方法不返回值,则返回NoneType:

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

您需要检查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
Run Code Online (Sandbox Code Playgroud)

Guido说只用于is检查,None因为is身份检查更加健壮.不要使用平等操作,因为那些可以吐出自己的冒泡实施. Python的编码风格指南 - PEP-008

NoneTypes是Sneaky,可以从lambdas偷偷进入:

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

NoneType不是有效的关键字:

a = NoneType     #NameError: name 'NoneType' is not defined
Run Code Online (Sandbox Code Playgroud)

连接None和字符串:

bar = "something"
foo = None
print foo + bar    #TypeError: cannot concatenate 'str' and 'NoneType' objects
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?

Python的解释器将您的代码转换为pyc字节码.Python虚拟机处理了字节码,它遇到了一个循环结构,表示迭代包含None的变量.通过__iter__在None上调用方法来执行该操作.

没有__iter__定义方法,所以Python的虚拟机会告诉你它看到了什么:NoneType没有__iter__方法.

这就是为什么Python的鸭子打字意识形态被认为是坏的.程序员用变量做了一些完全合理的事情,并且在运行时它被None污染了,python虚拟机试图继续攻击,并在整个地毯上掀起一堆无关的废话.

Java或C++没有这些问题,因为这样的程序不允许编译,因为你没有定义在None发生时要做什么.Python为程序员提供了很多绳索,可以让你做很多事情,这些事情在特殊情况下是不可能的.Python是一个肯定的人,说是先生,当它阻止你自己伤害时,就像Java和C++一样.

  • 嗯...如果您将`null`传递给需要任何集合类型的函数,Java将会出现本质上相同的问题。C ++对于`nullptr`会有同样的问题(但通常只是在段错误中死掉)(当然,好的C ++很少使用指针,但是您展示的是不好的Python,而坏的C ++可能在运行时死于)也为null)。Python在这里做正确的事;它不是“继续前进”,而是在您尝试将“无”用于任何“无”无法做的事情时出错。您的问题不是Python,而是动态类型的语言。 (3认同)
  • (a)混淆`NoneType`和`None`(b)认为`NameError:name'NonType'未定义`和'TypeError:无法连接'str'和'NoneType'对象`与'TypeError:'相同NoneType'对象不可迭代'(c)Python和java之间的比较是"一堆无关的废话" (2认同)

Joh*_*hin 63

代码:for row in data:
错误消息:TypeError: 'NoneType' object is not iterable

抱怨哪个对象?选择两个,rowdata.在for row in data哪,需要可迭代?只有data.

有什么问题data?它的类型是NoneType.只有None类型NoneType.所以data is None.

您可以在IDE中进行验证,也可以print "data is", repr(data)for语句之前插入并重新运行.

想想下一步你需要做什么: 如何表示"无数据"?我们写一个空文件吗?我们是否提出异常或记录警告或保持沉默?


gun*_*gor 17

另一件可能产生此错误的事情是当你设置的东西等于函数的返回值时,却忘了实际返回任何东西.

例:

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)
Run Code Online (Sandbox Code Playgroud)

这是一个很难发现的错误,因为如果在其中一个迭代上行变量为None,也会产生错误.发现它的方法是跟踪在最后一行而不是在函数内部失败.

如果你只从一个函数返回一个变量,我不确定是否会产生错误...我怀疑错误"'NoneType'对象在Python中不可迭代"在这种情况下实际上暗示"嘿,我正在尝试迭代返回值,按顺序将它们分配给这三个变量,但我只得到无迭代"

  • 这正是把我带到这里的原因。那么针对这种情况的 Pythonic 解决方案是什么? (2认同)

小智 8

这意味着数据变量传递None(类型为NoneType),它等效于什么.因此,它无法像列表一样进行迭代,就像您尝试的那样.

  • @deltanine 我认为这会使很多问题更难以检测。我很高兴 None 与空的可迭代对象不同。如果你想要你描述的行为,只需使用 `for row in data 或 []:` (4认同)
  • 如果只是像一个空列表一样迭代就好了......会获得更清晰的代码和更少的错误检查 (3认同)

cle*_*lee 7

你用这样的参数调用write_file:

write_file(foo, bar)
Run Code Online (Sandbox Code Playgroud)

但是你没有正确定义'foo',或者你的代码中有一个拼写错误,所以它创建了一个新的空变量并将其传入.