Co oznacza błąd TypeError: 'NoneType' object is not iterable
?
Dostaję to na tym kodzie Pythona:
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)
None
jest wymuszony jako sekwencja, musi wytworzyć pustą sekwencję, całkowicie nieszkodliwą.None
nigdy nie jest do niczego zmuszany . MającNone
cicho zachowywać się jak błędy innych rodzajów skór; to przeciwieństwo „nieszkodliwego”. Jeśli potrzebujesz fałszywego symbolu zastępczego dla pustej sekwencji, możesz użyć()
lub''
/""
, z których oba są singletonami i można je załadować równie tanio jakNone
. Jeśli chcesz wyrazić zgodę na ciche traktowanie czegoś fałszywego jako pustej sekwencji, możesz to zrobićfor row in data or ():
, ale nikt tego nie robi, ponieważ przekazanieNone
do funkcji oczekującej sekwencji jest błędem, który nie powinien przejść cicho.Odpowiedzi:
Oznacza to, że wartość
data
jestNone
.źródło
for
pętlę zamiast zgłaszać wyjątek. Projekt Pythona jest tutaj wadliwy. GdyNone
jest traktowany jako iterowalny, musi zwracać przynajmniej pustą listę. Ten wyjątek nigdy nie pomógł nikomu w prawdziwym życiu, poza zmuszeniem nas do wprowadzenia kilku brzydkichif data is not None:
sposobów obsługi.fieldlist
takDictWriter
jestNone
!for i in data or []
data
jest, czy nieNone
, ale pozwolenie na wystąpienie wyjątku. Ty chcesz konsumentów swojego API wiedzieć kiedy używałem go nieprawidłowo. AkceptacjaNone
jako pusta sekwencja pozwoliłaby takim błędommylist = mylist.extend(morestuff)
ukryć się jeszcze dłużej; myślą, że wydaliextend
alist
(i zrobili, ale natychmiast zastąpili goNone
), a następnie przekazują go do funkcji OP i zastanawiają się, dlaczego plik jest pusty, bez żadnych błędów.Wyjaśnienie błędu: Obiekt „NoneType” nie jest iterowalny
W python2 NoneType jest typem None. W Python3 NoneType jest klasą None, na przykład:
Iteracja po zmiennej, która ma wartość None kończy się niepowodzeniem:
Metody Pythona zwracają NoneType, jeśli nie zwracają wartości:
Musisz sprawdzić konstrukcje zapętlające dla NoneType w następujący sposób:
Guido mówi, że używaj tylko
is
do sprawdzania,None
ponieważis
jest bardziej odporny na sprawdzanie tożsamości. Nie używaj operacji równościowych, ponieważ mogą one same wypluć wybuchowe zapalenie. Wytyczne dotyczące stylu kodowania w Pythonie - PEP-008NoneTypes są Sneaky i mogą wkraść się z lambd:
NoneType nie jest prawidłowym słowem kluczowym:
Łączenie
None
i ciąg znaków:Co tu się dzieje?
Interpreter Pythona przekonwertował twój kod na kod bajtowy pyc. Maszyna wirtualna Pythona przetworzyła kod bajtowy, napotkała konstrukcję zapętloną, która mówi, że wykonuje iterację po zmiennej zawierającej None. Operacja została wykonana przez wywołanie
__iter__
metody na None.Żadna nie ma
__iter__
zdefiniowanej metody, więc maszyna wirtualna Pythona mówi ci, co widzi: że NoneType nie ma__iter__
metody.Właśnie dlatego ideologia pisania na klawiaturze w Pythonie jest uważana za złą. Programista robi coś całkiem rozsądnego ze zmienną i w czasie wykonywania zostaje ona skażona przez Brak, maszyna wirtualna Pythona próbuje się do niej przyłączyć i wymiotuje po całym dywanie garść niepowiązanych bzdur.
Java lub C ++ nie ma tych problemów, ponieważ taki program nie mógłby się kompilować, ponieważ nie zdefiniowano, co zrobić, gdy wystąpi Brak. Python daje programiście mnóstwo liny do powieszenia, pozwalając ci robić wiele rzeczy, od których nie można oczekiwać, że zadziałają w wyjątkowych okolicznościach. Python jest człowiekiem na tak, mówiąc tak, proszę pana, gdy ma to na celu powstrzymanie cię przed wyrządzeniem sobie krzywdy, tak jak robią to Java i C ++.
źródło
NoneType
iNone
(b) myśli, żeNameError: name 'NoneType' is not defined
iTypeError: cannot concatenate 'str' and 'NoneType' objects
są tym samym, coTypeError: 'NoneType' object is not iterable
(c) porównanie Pythona i javy to „garść niepowiązanych bzdur”null
do funkcji oczekującej dowolnego typu kolekcji. C ++ miałby ten sam problem (ale generalnie po prostu ginie w segfault bez zgłaszania przyczyny) dlanullptr
(wprawdzie dobry C ++ rzadko używa wskaźników, ale to, co pokazałeś, to zły Python, a zły C ++ może również umrzeć w czasie wykonywania z null) . Python robi tutaj właściwą rzecz; to nie jest „żołnierz”, to błąd w momencie, gdy próbujesz użyćNone
czegoś,None
czego nie możesz zrobić. Twój problem nie dotyczy Pythona, ale ogólnie języków dynamicznie typowanych.Kod:
for row in data:
Komunikat o błędzie:
TypeError: 'NoneType' object is not iterable
Na jaki przedmiot narzeka? Do wyboru dwa
row
idata
. Wfor row in data
, która musi być iterowalna? Tylkodata
.W czym problem
data
? Jego typ toNoneType
.None
Ma tylko typNoneType
. A więcdata is None
.Możesz to sprawdzić w IDE lub wstawiając np.
print "data is", repr(data)
Przedfor
instrukcją i uruchamiając ponownie.Zastanów się, co musisz zrobić dalej: jak należy przedstawić „brak danych”? Czy piszemy pusty plik? Czy zgłaszamy wyjątek, rejestrujemy ostrzeżenie lub milczymy?
źródło
Inną rzeczą, która może spowodować ten błąd, jest ustawienie wartości równej zwrotowi z funkcji, ale zapomnieliśmy o zwróceniu czegokolwiek.
Przykład:
Jest to trochę trudny do wykrycia błąd, ponieważ błąd można również wygenerować, jeśli zmienna wierszowa ma wartość None w jednej z iteracji. Sposobem na to jest to, że śledzenie kończy się niepowodzeniem w ostatnim wierszu, a nie w funkcji.
Jeśli zwracasz tylko jedną zmienną z funkcji, nie jestem pewien, czy błąd zostałby wygenerowany ... Podejrzewam, że błąd „Obiekt 'NoneType' nie jest iterowalny w Pythonie” w tym przypadku oznacza to „Hej, próbuję aby iterować po zwracanych wartościach, aby przypisać je do tych trzech zmiennych w kolejności, ale otrzymuję tylko None do iteracji ”
źródło
Oznacza to, że zmienna data przekazuje wartość None (która jest typu NoneType), jej odpowiednik dla niczego . Więc nie może być iterowalne jako lista, tak jak próbujesz to zrobić.
źródło
for row in data or []:
Wołasz write_file z następującymi argumentami:
Ale nie zdefiniowałeś poprawnie 'foo' lub masz literówkę w kodzie, tak że tworzy nową pustą zmienną i przekazuje ją.
źródło
Dla mnie był to przypadek posiadania mojej czapki Groovy zamiast Pythona 3.
Zapomniałem
return
słowa kluczowego na końcudef
funkcji.Przez kilka miesięcy nie pisał na poważnie Pythona 3. Czy myślałem, że ostatnie stwierdzenie ocenione w rutynach zostało zwrócone w sposób Groovy.
Wykonałem kilka iteracji, patrząc na ślad stosu, wstawiając
try: ... except TypeError: ...
debugowanie blokowe / przechodzenie przez kod, aby dowiedzieć się, co jest nie tak.Rozwiązanie komunikatu na pewno nie sprawiło, że błąd wyskoczył na mnie.
źródło