TypeError: 'NoneType'オブジェクトはPythonでは反復可能ではありません


145

エラーとは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での私の厄介な失望の1つです。ときにNoneシーケンスとしてに強制され、それは完全に無害で、空のシーケンスを生成しなければなりません。
ネヘム2017

7
@nehemiah:Pythonは強く型付けされています(静的に型付けされていないだけです)。何にNoneも強制されない。持つ他のタイプの皮のエラーのように振る舞う静か。それは「無害」の反対です。空のシーケンスに偽のプレースホルダーが必要な場合は、/ を使用できます。どちらもシングルトンであり、と同じくらい安価にロードできます。あなたがオプトイン静かに空のシーケンスとして何もfalsyの治療にしたい場合は、行うことができ、誰も渡しているので、ということませんシーケンスを期待して機能することは黙って渡してはならないエラーです。None()''""Nonefor row in data or ():None
ShadowRanger 2018年

回答:


203

datais の値を意味しますNone


37
正解ですが、ここで意図する一般的なシナリオの作成者はfor、例外を発生させる代わりにループを完全にスキップすることです。Pythonの設計にはここに欠陥があります。Noneが反復可能として扱われる場合、少なくとも空のリストを返す必要があります。この例外は、醜いif data is not None:種類の処理をいくつか挿入する以外に、実際の人を助けることはありませんでした。
ネヘム2017

より具体的な答えは、fieldlistfor for DictWriterNone
Arklur 2017

30
試してみるfor i in data or []
BMW

4
@nehemiah:実際、正しいアプローチは、であるかどうかをチェックするのdataではなくNone、例外を発生させることです。あなたはしたい、彼らは間違ってそれを使用しましたときに、あなたのAPIの消費者が知っています。None空のシーケンスとして受け入れると、のようなミスが発生しmylist = mylist.extend(morestuff)、さらに長く隠れるようになります。彼らは自分たちがextendedしたと思ってlist(そうしたのですが、すぐにそれをに置き換えましたNone)、それをOPの関数に渡して、ファイルが空で、なんらエラーが発生していないのかと思います。
ShadowRanger 2018年

83

エラーの説明:「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のコーディングスタイルガイドライン-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のメソッドをました。

Noneには__iter__メソッドが定義されていないため、Pythonの仮想マシンは何が見えるかを通知します。NoneTypeには__iter__メソッドがありません。

これが、Pythonのダックタイピングのイデオロギーが悪いと見なされている理由です。プログラマーは変数を使用して完全に妥当な処理を実行し、実行時にNoneで汚染され、Python仮想マシンが兵士を配置しようとし、カーペット全体に無関係なナンセンスの束を吐き出します。

Noneが発生したときに何をするかを定義していないため、そのようなプログラムはコンパイルできないため、JavaまたはC ++にはこれらの問題はありません。Pythonは、例外的な状況下では機能することが期待できない多くのことを実行できるようにすることで、プログラマーに多くのロープをかけることができます。Pythonはイエスマンであり、JavaやC ++がそうであるように、自分への危害を防ぐために、イエス・サーと言っています。


2
(a)混乱しNoneTypeNone(b)は(c)Pythonとjavaの比較は「無関係なナンセンスの束」と同じであるNameError: name 'NoneType' is not definedと考えるTypeError: cannot concatenate 'str' and 'NoneType' objectsTypeError: 'NoneType' object is not iterable
John Machin

3
うーん... Javaはnull、コレクション型を期待する関数に渡した場合、本質的に同じ問題を抱えているでしょう。C ++でも同じ問題が発生します(ただし、通常、原因を報告せずにsegfaultで停止するだけnullptrです)。 。Pythonはここで正しいことをしています。それは「頼りになる」ことではなくNone、何かNoneができないことに使用しようとした瞬間にエラーを出します。あなたの問題はPythonにあるのではなく、一般に動的に型付けされた言語にあります。
ShadowRanger 2018年

63

コード:for row in data:
エラーメッセージ:TypeError: 'NoneType' object is not iterable

どのオブジェクトが不満を持っていますか?2つの選択、rowおよびdata。ではfor row in data、どれが反復可能である必要がありますか?のみdata

何が問題なのdataですか?そのタイプはNoneTypeです。NoneタイプのみNoneTypeです。ですからdata is None

IDEでこれを確認するかprint "data is", repr(data)forステートメントの前などに挿入して再実行します。

次に何をする必要があるかを考えて ください。「データなし」をどのように表す必要がありますか?空のファイルを書き込みますか?例外を発生させるか、警告をログに記録するか、それとも黙っていますか?


18

このエラーを生成する可能性のあるもう1つのことは、関数からの戻り値に等しい値を設定しているが、実際には何も返さないことです。

例:

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になった場合にもエラーが発生する可能性があるため、これは見つけるのが難しいエラーの少しです。それを見つける方法は、トレースが関数内ではなく最後の行で失敗することです。

関数から1つの変数しか返さない場合、エラーが発生するかどうかはわかりません...この場合のエラー「 'NoneType'オブジェクトはPythonでは反復可能ではない」は、実際には「ねえ、試しています戻り値を繰り返し処理してこれらを3つの変数に順番に割り当てますが、Noneのみが繰り返し処理されます」


1
これがまさに私をここに連れてきたものです。それでは、そのような状況に対するPythonicソリューションは何でしょうか?
Dr_Zaszuś

1
ここではいくつかの助けがあるように思える:stackoverflow.com/questions/1274875/...
Dr_Zaszuś

8

これは、データ変数は、(タイプNoneTypeある)なし、のためにそれに相当渡していないことを意味何も。したがって、あなたがやろうとしているように、リストとして反復可能にすることはできません。


1
空のリストのように反復するだけでいいです...よりクリーンなコードになり、エラーチェックが少なくなります
Deltanine

4
@deltanineこれは、多くの問題を検出するのがより難しくなると思います。Noneが空のイテラブルと違うのはうれしいです。説明された動作が必要な場合は、次のように使用してくださいfor row in data or []:
Mark

7

次のような引数でwrite_fileを呼び出しています。

write_file(foo, bar)

しかし、 'foo'を正しく定義していないか、コードにタイプミスがあり、新しい空の変数を作成してそれを渡しています。


1

私にとっては、Groovyの帽子をかぶったケースでしたは、Python 3のではなく。

関数returnの最後のキーワードを忘れましたdef

数か月間Python 3を本格的にコーディングしていませんでした。ルーチンで評価された最後のステートメントがGroovyの方法で返されると考えていました。

何回か繰り返して、スタックトレースを確認し、try: ... except TypeError: ...コードのブロックデバッグ/ステップ実行を挿入して、何が問題だったかを突き止めました。

メッセージの解決策は確かに私にエラーを飛び出させませんでした。


ありがとうございました。これはまさに私の問題でした。私は夢中になりそうでした...
J.ブレットカニンガム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.