TypeError:“NoneType”对象在 Python 中不可迭代
Posted
技术标签:
【中文标题】TypeError:“NoneType”对象在 Python 中不可迭代【英文标题】:TypeError: 'NoneType' object is not iterable in Python 【发布时间】:2011-04-22 16:34:11 【问题描述】:错误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)
【问题讨论】:
这是我对 Python 的恼人失望之一。当None
被强制转换为序列时,它必须产生一个空序列,完全无害。
@nehemiah:Python 是强类型的(只是不是静态类型的)。 None
永远不会被强制anything。让None
像其他类型一样默默地隐藏错误;那是“无害”的相反。如果你需要一个虚假的占位符来表示空序列,你可以使用()
或''
/""
,它们都是单例,并且可以像None
一样便宜地加载。如果您想选择以静默方式将任何虚假的内容视为空序列,您可以执行for row in data or ():
,但没有人这样做,因为将None
传递给期望序列的函数是一个不应静默传递的错误.
在 python 2 中安装不再支持 python 2 的模块时,您也可能会收到此错误,例如***.com/q/63346648/838494
@nehem 你一定是 javascript 的粉丝。
@MattYoon JS 做对了很多事情。
【参考方案1】:
表示data
的值为None
。
【讨论】:
正确,但是作者在这里打算完全跳过for
循环而不是引发异常。 Python 的设计在这里有缺陷。当None
被视为可迭代时,它必须至少返回空列表。除了让我们插入一些丑陋的if data is not None:
处理之外,这个例外对现实生活中的任何人都没有帮助。
对于更具体的答案,如果DictWriter
的fieldlist
是None
,则可能会发生这种情况!
试试for i in data or []
@nehemiah:其实正确的做法不是检查data
是不是None
,而是让异常发生。您希望 API 的使用者知道他们何时错误地使用了它。接受None
为空序列会让mylist = mylist.extend(morestuff)
之类的错误隐藏得更久;他们认为他们 extend
ed a list
(他们确实做到了,但随后立即将其替换为 None
),然后将其传递给 OP 的函数,并想知道为什么文件是空的,没有引发任何错误。 【参考方案2】:
您正在使用如下参数调用 write_file:
write_file(foo, bar)
但是您没有正确定义“foo”,或者您的代码中有错字,因此它正在创建一个新的空变量并将其传入。
【讨论】:
【参考方案3】:这意味着数据变量传递的是None(类型为NoneType),它相当于nothing。所以它不能像你试图做的那样作为一个列表进行迭代。
【讨论】:
如果像一个空列表一样迭代就好了……这样代码更简洁,错误检查更少 @deltanine 我认为这会使很多问题更难检测。我很高兴 None 与空的可迭代对象不同。如果你想要你描述的行为,只需使用for row in data or []:
@Mark 如果它返回空列表,它会更干净。如果您希望它失败,您可以随时添加一行 if data is None: raise
【参考方案4】:
代码: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
语句之前,然后重新运行。
想想你接下来需要做什么: “无数据”应该如何表示?我们写一个空文件吗?我们是引发异常、记录警告还是保持沉默?
【讨论】:
【参考方案5】:错误解释:“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
Guido 说只使用is
来检查None
,因为is
对身份检查更健壮。不要使用相等操作,因为它们会产生自己的冒泡实现。 Python's Coding Style Guidelines - PEP-008
NoneTypes 是偷偷摸摸的,可以从 lambdas 潜入:
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 的变量。该操作是通过在 None 上调用 __iter__
方法来执行的。
None 没有定义 __iter__
方法,所以 Python 的虚拟机告诉你它看到了什么:NoneType 没有 __iter__
方法。
这就是为什么Python's duck-typing 意识形态被认为是坏的。程序员对变量做了一些完全合理的事情,在运行时它被 None 污染,python 虚拟机试图继续前进,并在地毯上吐出一堆不相关的废话。
Java 或 C++ 没有这些问题,因为这样的程序不会被允许编译,因为你还没有定义当 None 发生时要做什么。 Python 允许你做很多在特殊情况下不应该做的事情,从而给程序员提供了很多可以吊死自己的绳索。 Python 是一个“是”的人,当它阻止你伤害自己时说“是”,先生,就像 Java 和 C++ 一样。
【讨论】:
(a) 混淆NoneType
和None
(b) 认为NameError: name 'NoneType' is not defined
和TypeError: cannot concatenate 'str' and 'NoneType' objects
和TypeError: cannot concatenate 'str' and 'NoneType' objects
一样 (c) Python 和java 比较是“一堆无关的废话”
嗯...如果您将null
传递给期望任何集合类型的函数,Java 将遇到基本相同的问题。对于nullptr
,C++ 也会有同样的问题(但通常只是在段错误中死掉而不报告原因)(诚然,好的 C++ 很少使用指针,但你所展示的是糟糕的 Python,而糟糕的 C++ 可能会在运行时从也为空)。 Python在这里做的是正确的事情;这不是“继续战斗”,当您尝试使用None
做任何None
做不到的事情时,它就会出错。您的问题不在于 Python,而在于一般的动态类型语言。【参考方案6】:
另一个可能产生此错误的情况是,当您设置的值等于函数的返回值,但忘记实际返回任何值。
例子:
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' object is not iterable in Python”在这种情况下实际上暗示“嘿,我'正在尝试迭代返回值以按顺序将它们分配给这三个变量,但我只得到 None 来迭代"
【讨论】:
这正是把我带到这里的原因。那么针对这种情况的 Pythonic 解决方案是什么? 这里好像有帮助:***.com/questions/1274875/… Dr_Zaszus 这也是我的问题。这个特定的答案只是说确实存在问题。而且,接受的答案基本上也只是说“是的,这会引发错误”。整个线程没有解决潜在问题的实际、良好、公认的实践答案。提到的最佳解决方案是在注释中,即添加“if data is not None:”,这是一个丑陋的解决方案。【参考方案7】:对我来说,这是我的 Groovy hat 而不是 Python 3 的情况。
忘记了def
函数末尾的return
关键字。
已经有几个月没有认真编写 Python 3 代码了。认为在例程中评估的最后一条语句是按照 Groovy(或 Rust)方式返回的。
进行了几次迭代,查看堆栈跟踪,插入 try: ... except TypeError: ...
块调试/单步执行代码以找出问题所在。
消息的解决方案当然没有让我跳出错误。
【讨论】:
【参考方案8】:当你得到无异常时继续循环,
示例:
a = None
if a is None:
continue
else:
print("do something")
这可以是来自 DB 或 excel 文件的任何可迭代对象。
【讨论】:
【参考方案9】:这还取决于您使用的 Python 版本。看到 python 3.6 和 python 3.8 中抛出的不同错误消息如下,这是我的问题
Python 3.6Python 3.8(a,b) = None Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'NoneType' object is not iterable
(a,b) = None Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: cannot unpack non-iterable NoneType object
【讨论】:
以上是关于TypeError:“NoneType”对象在 Python 中不可迭代的主要内容,如果未能解决你的问题,请参考以下文章
在执行并行 ssh 时获取“TypeError:'NoneType' 对象不可迭代”
TypeError:“NoneType”对象在函数中不可下标
Anvil 错误:TypeError:“NoneType”对象不可下标
TypeError:调用键函数时“NoneType”对象不可迭代