Як виправити TypeError: об’єкт «NoneType» не можна ітерувати в Python

Python це популярна та універсальна мова програмування, але, як і будь-яка інша мова, вона може видавати помилки, які можуть бути неприємними для налагодження. Однією з поширених помилок, з якими стикаються розробники, є TypeError: об’єкт «NoneType» не можна повторювати. У цій статті ми розглянемо різні сценарії виникнення цієї помилки та запропонуємо практичні рішення, які допоможуть вам ефективно її вирішити.

Розуміння помилки: об’єкт NoneType не можна ітерувати

Повідомлення про помилку TypeError: об’єкт «NoneType» не можна повторювати в Python зазвичай виникає, коли ви намагаєтеся виконати ітерацію по об’єкту, який має значення Жодного . Ця помилка виникає, оскільки None не є ітераційним, тобто ви не можете проходити через нього, як зі списками, кортежами чи іншими ітерованими об’єктами.

синтаксис: TypeError: об’єкт «NoneType» не можна повторювати

Причини TypeError: об’єкт «NoneType» не можна повторювати

  • Відсутня заява про повернення
  • Недійсна відповідь API
  • Ітерація по змінній зі значенням None
  • Немає Помилка типу в класах
  • Лямбда-функції та помилка NoneType

Відсутня заява про повернення

Одним із найпоширеніших сценаріїв, що призводять до цієї помилки, є відсутність оператора return у функції. Скажімо, у нас є функція, яка має повертати a список чисел, але ми забуваємо включити оператор return:

Python3




def> generate_numbers():> > numbers> => [> 1> ,> 2> ,> 3> ,> 4> ,> 5> ]> > # Missing return statement> result> => generate_numbers()> for> num> in> result:> > print> (num)>

Вихід

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 1 line 6 3 # Missing return statement 5 result = generate_numbers() ---->6 для num у результаті: 7 print(num) TypeError: об’єкт 'NoneType' не піддається ітерації 

В цьому випадку, ' generate_numbers()' нічого не повертає, тобто повертає нічого. Коли ми намагаємося повторити результат, ми зіткнемося з « TypeError' тому що ми не можемо повторити None.

Рішення: Забезпечте належне повернення

Щоб виправити цю помилку, переконайтеся, що наша функція повертає очікуване значення. У цьому прикладі ми повинні додати оператор return до ‘generate_numbers()’:

Python3




def> generate_numbers():> > numbers> => [> 1> ,> 2> ,> 3> ,> 4> ,> 5> ]> > return> numbers> result> => generate_numbers()> for> num> in> result:> > print> (num)>

Вихід

1 2 3 4 5 

тепер, generate_numbers() повертає список чисел, і помилку вирішується.

Недійсна відповідь API

Ще один сценарій, коли ви можете зіткнутися з цією помилкою, це під час роботи з API . Припустімо, ми робимо запит API для отримання даних, але API повертає None замість очікуваних даних:

Python3




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)>

Вихід

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 2 line 11 8 return None 10 data = fetch_data() --->11 для елемента в даних: 12 print(item) TypeError: об’єкт 'NoneType' не піддається ітерації 

Якщо API запит не вдасться або не повертається Ні, ми отримаємо a 'TypeError' під час спроби повторити дані.

Рішення: перевірте відповідь API

Щоб впоратися з цією ситуацією, ми повинні перевірити відповідь API, перш ніж намагатися її повторити. Ось покращена версія коду:

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)>

Якщо код стану не 200, це означає, що виникла проблема з API запит. У цьому випадку ми повертаємо порожній список [] як значення заповнювача замість None. Повернення порожнього списку дозволяє нам уникнути «NoneType» помилка під час спроби повторити дані відповіді далі в коді.

Ітерація по змінній зі значенням None

Цей сценарій простий і поширений. Це відбувається, коли ми намагаємося виконати цикл (ітерацію) над змінною, яка має значення None:

Python3




my_list> => None> for> item> in> my_list:> > print> (item)>

Вихід

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 3 line 2 1 my_list = None ---->2 для елемента в my_list: 3 print(item) TypeError: об’єкт 'NoneType' не піддається ітерації 

У цьому сценарії змінна ' мій_список встановлено значення Немає. Коли цикл for намагається виконати ітерацію «мій_список» , він стикається з TypeError: об’єкт «NoneType» не можна повторювати. Ця помилка виникає тому, що None не є ітерованим об’єктом, і ми не можемо пройти через нього.

Рішення: забезпечення наявності Iterable перед циклом

Щоб виправити цю помилку, нам потрібно це переконатися «мій_список» містить ітерований об’єкт (наприклад, список, кортеж тощо) перед спробою його повторення. Додавання перевірки лайка якщо my_list не None перед циклом гарантує, що код усередині циклу виконується лише якщо мій_список не є Жодним, запобігаючи «NoneType» помилка.

Python3




my_list> => None> if> my_list> is> not> None> :> > for> item> in> my_list:> > print> (item)>

Немає Помилка типу в класах

Заняття в Python також можна зіткнутися «NoneType» помилки, особливо при роботі з методами, які повертають None. Розглянемо клас із методом, який не повертає жодного значення.

Припустімо, що у нас є клас з назвою «Студент». У цьому класі ми хочемо зберегти ім’я студента та його оцінки. Клас має метод під назвою 'get_grades()' який, за логікою, мав би повернути оцінки студента. У цій ситуації студент на ім’я « Аліша створюється зі списком оцінок. Намір полягає в тому, щоб перевірити, чи будь-який з оцінок Аліші перевищує або дорівнює 90, і надрукувати їх

Ось вихідний код:

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)>

Вихід

--------------------------------------------------------------------------- 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 для оцінки в student.get_grades(): 14 якщо оцінка>=90: 15 print(grade) TypeError: об’єкт 'NoneType' не піддається ітерації 

Питання полягає в 'get_grades()' метод. Хоча він друкує оцінки, він їх не повертає. Коли ми намагаємося прокрутити 'student.get_grades()' , він друкує оцінки, але не дає вам жодних значень для роботи в циклі.

Отже, коли ми намагаємося повторити результат ‘student.get_grades()’, воно неявно повертається «Жодного» оскільки немає явного оператора return у 'get_grades()' метод. Python вважає це None, що не можна повторювати. В результаті ми стикаємося з a TypeError: об’єкт «NoneType» не можна повторювати помилка.

Рішення: повернення відповідних значень із методів класу

Щоб вирішити цю проблему, нам потрібно змінити 'get_grades()' метод. Замість того, щоб просто друкувати оцінки, він повинен повертати їх. Повернення оцінок означає надання ітерованого (у цьому випадку списку оцінок) викликаючому методу. Повертаючи оцінки, метод стає повторюваним, і цикл може працювати за призначенням.

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)>

Отже, у цьому виправленому коді 'get_grades()' метод повертає 'self.grade', який є списком оцінок. Коли ми повторюємо 'student.get_grades()' , ми переглянемо список оцінок, і їх не буде «NoneType» помилка, оскільки ми повторюємо дійсний ітерований об’єкт.

Вихід

90 92 

Лямбда-функції та помилка NoneType

Помилка TypeError: об’єкт «NoneType» не можна повторювати може виникнути в лямбда-функції коли функція лямбда повертає None у певних ситуаціях. Зазвичай це відбувається, коли ми умовно повертаємо None для певних вхідних значень. Коли ми намагаємося повторити результат лямбда-функції, яка повертає None, ми стикаємося з цією помилкою.

приклад: У цьому прикладі, якщо вхід x не більше 0 (x>0) , лямбда-функція повертає None. Коли ми намагаємося повторити результат, ми намагаємось виконати ітерацію None, викликаючи TypeError: об’єкт «NoneType» не можна повторювати помилка.

Python3




my_lambda> => lambda> x: x> *> 2> if> x>> 0> else> None> result> => my_lambda(> -> 1> )> for> item> in> result:> > print> (item)>

Вихід

--------------------------------------------------------------------------- TypeError Traceback (most recent call last) c:Userspractice.ipynb Cell 5 line 3 1 my_lambda = lambda x: x * 2 if x>0 else None 2 result = my_lambda(-1) ----> 3 for item in result: 4 print(item) TypeError: 'NoneType' object is not iterable 

Рішення: забезпечення повторюваних результатів

Щоб виправити цю помилку, ми повинні обробити випадок, коли лямбда-функція повертає None. Один із способів впоратися з цим — надати ітерацію за замовчуванням (наприклад, порожній список) у випадку Жодного. Ось виправлений код:

Python3




my_lambda> => lambda> x: [x> *> 2> ]> if> x>> 0> else> []> result> => my_lambda(> -> 1> )> for> item> in> result:> > print> (item)>

Вихід: У цьому фіксованому коді, лямбда-функція повертає список, що містить х * 2 якщо «х» більше 0. Якщо «х» не перевищує 0 (як у випадку -1), він повертає порожній список. Тепер ми можемо повторювати результат, не зустрічаючи «NoneType» помилка.