Я пытаюсь изучить метод __iter__, и это ошибка, которую я получаю:
print(i for i in my_iter)
TypeError: iter() returned non-iterator of type 'NoneType'
Мой код выглядит следующим образом:
class IterMethod:
def __init__(self, last_elem):
pass
def __iter__(self):
i = 5
while i <= 50:
print(f"this is {i}")
i = i + 10
my_iter = IterMethod(60)
print(i for i in my_iter)
Не могли бы вы объяснить, почему? Спасибо!
Какова цель last_elem
?
last_elem
здесь бесполезно. Я просто написал это вместо 50 в цикле while, но забыл удалить
(Извините, в спешке с ответом я не объяснил, почему произошла ошибка. Это редактирование должно включать объяснение.)
Объяснение:
TypeError: iter() returned non-iterator of type 'NoneType'
означает, что __iter__()
не возвращал никаких значений (по умолчанию это означает None для «Нет возвращаемого значения» (в данном конкретном случае)). (Смущает, я знаю, что это означает, что технически он возвращает None.)
__iter__
должен возвращать значение каждый раз, когда он «генерирует» значение внутри функции. Если он не возвращает значение, вы получаете ошибку.
Обратите внимание, что когда я говорю return a value
, вы не используете return
. В случае с итер (которая по сути является функцией генератора) вам нужно использовать yield
. Если вас это смущает, пожалуйста, прочитайте, что такое генераторы. т.е. по адресу https://www.geeksforgeeks.org/generators-in-python/ (например, и не связанный с этой ссылкой).
Так...
Две проблемы плюс одно изменение (как предложил @DanielWalker):
i = i + 10
к
i += 10
print(i for i in my_iter)
.Как есть, это печатает подпись генератора. Что вы хотите:
print(list(i for i in my_iter))
yield
должен быть оператор __iter__
.В зависимости от того, хотите ли вы, чтобы значение i
было, у вас есть следующие варианты:
class IterMethod:
def __init__(self, last_elem):
pass
def __iter__(self):
i = 5
while i <= 50:
print(f"this is {i}")
i += 10
yield i
my_iter = IterMethod(60)
print(list(i for i in my_iter))
Итак, это выведет:
this is 5
this is 15
this is 25
this is 35
this is 45
[15, 25, 35, 45, 55]
Теперь, если вы хотите получить значение i
перед i = i + 10
,
class IterMethod:
def __init__(self, last_elem):
pass
def __iter__(self):
i = 5
while i <= 50:
print(f"this is {i}")
yield i
i += 10
my_iter = IterMethod(60)
print(list(i for i in my_iter))
Это выведет:
this is 5
this is 15
this is 25
this is 35
this is 45
[5, 15, 25, 35, 45]
@DanielWalker Так верно. Это изменит. Спасибо.
Спасибо. Это решило проблему, но не могли бы вы объяснить, что пытается сказать сообщение об ошибке? TypeError: iter() returned non-iterator of type 'NoneType'
Не понимаю логики non iterator of type none type
@VRM Ошибка возникает из-за того, что вы ничего не возвращаете и не даете с помощью метода итер.
Вам нужен
yield i
в блоке while. Вопрос о том, где вы хотите это, зависит от того, хотите ли вы, чтобы i было значением до или послеi = i + 10
.