Pyton to popularny i wszechstronny język programowania, ale jak każdy inny język, może powodować błędy, których debugowanie może być frustrujące. Jednym z typowych błędów napotykanych przez programistów jest TypeError: Obiekt „NoneType” nie jest iterowalny. W tym artykule przeanalizujemy różne scenariusze, w których może wystąpić ten błąd, i przedstawimy praktyczne rozwiązania, które pomogą Ci skutecznie sobie z nim poradzić.
Zrozumienie błędu: Obiekt NoneType nie jest iterowalny
Komunikat o błędzie TypeError: Obiekt „NoneType” nie jest iterowalny W Pyton zwykle ma to miejsce, gdy próbujesz iterować po obiekcie, który ma wartość Nic . Ten błąd jest zgłaszany, ponieważ None nie jest iterowalny, co oznacza, że nie można go przeglądać w pętli, tak jak w przypadku list, krotek lub innych iterowalnych obiektów.
składnia: TypeError: Obiekt „NoneType” nie jest iterowalny
Przyczyny błędu TypeError: Obiekt „NoneType” nie jest iterowalny
- Brak oświadczenia o zwrocie
- Nieprawidłowa odpowiedź API
- Iteracja po zmiennej o wartości Brak
- Brak Błąd typu w klasach
- Funkcje lambda i błąd NoneType
Brak oświadczenia o zwrocie
Jednym z najczęstszych scenariuszy prowadzących do tego błędu jest brak instrukcji return w funkcji. Załóżmy, że mamy funkcję, która ma zwrócić a lista liczb, ale zapominamy o dołączeniu instrukcji return:
Python3
def> generate_numbers():> >numbers>=> [>1>,>2>,>3>,>4>,>5>]> ># Missing return statement> result>=> generate_numbers()> for> num>in> result:> >print>(num)> |
>
>
Wyjście
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 1 line 6 3 # Missing return statement 5 result = generate_numbers() ---->6 dla liczby w wyniku: 7 print(num) TypeError: Obiekt 'NoneType' nie jest iterowalny>
W tym przypadku, ' generuj_liczby()” nic nie zwraca, co oznacza, że zwraca None. Kiedy spróbujemy iterować po wyniku, natkniemy się na „ TypBłąd ponieważ nie możemy iterować po None.
Rozwiązanie: Zapewnij prawidłowy zwrot
Aby naprawić ten błąd, upewnij się, że nasza funkcja zwraca oczekiwaną wartość. W tym przykładzie powinniśmy dodać instrukcję return do „generuj_liczby()”:
Python3
def> generate_numbers():> >numbers>=> [>1>,>2>,>3>,>4>,>5>]> >return> numbers> result>=> generate_numbers()> for> num>in> result:> >print>(num)> |
>
>
Wyjście
1 2 3 4 5>
Teraz, generuj_liczby() zwraca listę liczb i błąd zostaje rozwiązany.
Nieprawidłowa odpowiedź API
Innym scenariuszem, w którym możesz napotkać ten błąd, jest praca z Pszczoła . Załóżmy, że wysyłamy żądanie API w celu pobrania danych, ale interfejs API zwraca Brak zamiast oczekiwanych danych:
Python3
pogrubiony tekst CSS
import> requests> def> fetch_data():> >response>=> requests.get(>' https://api.openweathermap.org/data '>)> >if> response.status_code>=>=> 200>:> >return> response.json()> >else>:> >return> None> data>=> fetch_data()> for> item>in> data:> >print>(item)> |
>
>
Wyjście
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 2 line 11 8 return None 10 data = fetch_data() --->11 dla pozycji w danych: 12 print(item) TypeError: Obiekt 'NoneType' nie jest iterowalny>
Jeśli API żądanie nie powiedzie się lub zwróci Brak, otrzymamy komunikat „Błąd typu” podczas próby iteracji danych.
Rozwiązanie: Sprawdź odpowiedź API
Aby poradzić sobie z tą sytuacją, powinniśmy sprawdzić odpowiedź API przed próbą iteracji po niej. Oto ulepszona wersja kodu:
Python3
import> requests> def> fetch_data():> >response>=> requests.get(>' https://api.openweathermap.org/data '>)> >if> response.status_code>=>=> 200>:> >return> response.json()> >else>:> >return> [ ]> data>=> fetch_data()> for> item>in> data:> >print>(item)> |
>
>
Jeśli kod stanu nie ma wartości 200, oznacza to, że wystąpił problem z plikiem API wniosek. W tym przypadku zwracamy pustą listę [] jako wartość zastępczą zamiast Brak. Zwrócenie pustej listy pozwala nam uniknąć „Brak typu” błąd podczas próby iteracji danych odpowiedzi w dalszej części kodu.
Iteracja po zmiennej o wartości Brak
Ten scenariusz jest prosty i powszechny. Dzieje się tak, gdy próbujemy wykonać pętlę (iterację) po zmiennej, która ma wartość Brak:
Python3
my_list>=> None> for> item>in> my_list:> >print>(item)> |
>
>
Wyjście
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 3 line 2 1 my_list = None ---->2 dla pozycji na mojej_liście: 3 print(item) TypeError: Obiekt 'NoneType' nie jest iterowalny>
W tym scenariuszu zmienna „ moja lista' jest ustawiony na Brak. Kiedy pętla for próbuje wykonać iterację 'moja lista' , spotyka się z TypeError: Obiekt „NoneType” nie jest iterowalny. Ten błąd występuje, ponieważ None nie jest obiektem iterowalnym i nie możemy przez niego przechodzić pętlą.
Rozwiązanie: Zapewnienie obecności Iterable przed zapętleniem
Aby naprawić ten błąd, musimy się o to upewnić 'moja lista' zawiera obiekt iterowalny (taki jak lista, krotka itp.) przed próbą iteracji po nim. Dodanie czeku np jeśli moja_lista nie ma wartości Brak przed pętlą zapewnia, że kod wewnątrz pętli będzie wykonywany tylko wtedy, gdy moja lista nie jest Brak, zapobiegając „Brak typu” błąd.
Python3
my_list>=> None> if> my_list>is> not> None>:> >for> item>in> my_list:> >print>(item)> |
prosty program w Pythonie
>
>
Brak Błąd typu w klasach
Zajęcia W Pyton też można spotkać „Brak typu” błędy, szczególnie podczas pracy z metodami zwracającymi None. Rozważmy klasę z metodą, która nie zwraca żadnej wartości.
Załóżmy, że mamy klasę o nazwie 'Student'. Na tych zajęciach chcemy przechowywać imię i nazwisko ucznia oraz jego oceny. Klasa posiada metodę o nazwie „get_grades()” co logicznie rzecz biorąc powinno zwracać oceny ucznia. W tej sytuacji uczeń o imieniu „ Alisha tworzony jest z listą ocen. Zamiarem jest sprawdzenie, czy któraś z ocen Alishy jest wyższa lub równa 90 i wydrukowanie ich
Oto początkowy kod:
Python3
class> Student:> >def> __init__(>self>, name,grade):> >self>.name>=> name> >self>.grade>=> grade> > >def> get_grades(>self>):> > >print>(>self>.grade)> > > student>=> Student(>'Alisha'>,[>90>,>85>,>88>,>92>])> for> grade>in> student.get_grades():> >if> grade>>=>90>:> >print>(grade)> |
>
>
Wyjście
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 4 line 13 8 print(self.grade) 11 student = Student('Alisha',[90,85,88,92]) --->13 dla oceny w student.get_grades(): 14 jeśli ocena>=90: 15 print(ocena) TypeError: Obiekt 'NoneType' nie jest iterowalny> Problem leży w „get_grades()” metoda. Chociaż drukuje oceny, nie zwraca ich. Kiedy próbujemy przejść przez pętlę „student.get_grades()” , wypisuje oceny, ale nie podaje żadnych wartości, z którymi można pracować w pętli.
Tak więc, gdy próbujemy iterować po wyniku „student.get_grades()”, domyślnie powraca 'Nic' ponieważ nie ma wyraźnej instrukcji return w pliku „get_grades()” metoda. Pyton uważa to za None, które nie jest iterowalne. W rezultacie spotykamy A TypeError: Obiekt „NoneType” nie jest iterowalny błąd.
Rozwiązanie: Zwracanie odpowiednich wartości z metod klasowych
Aby rozwiązać ten problem, musimy zmodyfikować plik „get_grades()” metoda. Zamiast po prostu drukować oceny, powinien je zwrócić. Zwrócenie ocen oznacza udostępnienie iterowalnej wartości (w tym przypadku listy ocen) wywołującemu metodę. Zwracając oceny, metoda staje się iterowalna, a pętla może działać zgodnie z zamierzeniami.
Python3
class> Student:> >def> __init__(>self>, name,grade):> >self>.name>=> name> >self>.grade>=> grade> > >def> get_grades(>self>):> > >return> self>.grade> > > student>=> Student(>'Alisha'>,[>90>,>85>,>88>,>92>])> for> grade>in> student.get_grades():> >if> grade>>=>90>:> >print>(grade)> |
>
>
Zatem w tym poprawionym kodzie plik „get_grades()” metoda zwraca „samoocena”, czyli lista ocen. Kiedy będziemy iterować „student.get_grades()” , będziemy iterować po liście ocen i nie będzie żadnych „Brak typu” błąd, ponieważ iterujemy po prawidłowym obiekcie iterowalnym.
Wyjście
90 92>
Funkcje lambda i błąd NoneType
Błąd TypeError: Obiekt „NoneType” nie jest iterowalny może wystąpić w funkcje lambda gdy funkcja lambda zwraca None w pewnych sytuacjach. Zwykle dzieje się tak, gdy warunkowo zwracamy None dla określonych wartości wejściowych. Kiedy próbujemy iterować po wyniku funkcji lambda, która zwraca Brak, napotykamy ten błąd.
Przykład: W tym przykładzie, jeśli wejście X nie jest większa niż 0 (x>0) , funkcja lambda zwraca Brak. Kiedy próbujemy iterować po wyniku, próbujemy iterować po Braku, powodując TypeError: Obiekt „NoneType” nie jest iterowalny błąd.
Python3
my_lambda>=> lambda> x: x>*> 2> if> x>>0> else> None> result>=> my_lambda(>->1>)> for> item>in> result:> >print>(item)> |
>
>
Wyjście
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 5 line 3 1 my_lambda = lambda x: x * 2 if x>0 else Brak 2 wynik = my_lambda(-1) ----> 3 dla elementu w wyniku: 4 print(item) TypeError: Obiekt 'NoneType' nie jest iterowalny>
Rozwiązanie: Zapewnienie iterowalnych wyników
Aby naprawić ten błąd, powinniśmy zająć się przypadkiem, w którym funkcja lambda zwraca Brak. Jednym ze sposobów poradzenia sobie z tym jest zapewnienie domyślnej iterowalności (takiej jak pusta lista) w przypadku Nic. Oto poprawiony kod:
Python3
my_lambda>=> lambda> x: [x>*> 2>]>if> x>>0> else> []> result>=> my_lambda(>->1>)> for> item>in> result:> >print>(item)> |
>
>
Wyjście: W tym stałym kodzie funkcja lambda zwraca listę zawierającą x*2 Jeśli 'X' jest większa niż 0. Jeśli 'X' nie jest większa niż 0 (jak w przypadku -1), zwraca pustą listę. Teraz możemy iterować po wyniku bez napotykania „Brak typu” błąd.