为什么我会收到此错误? TypeError:iter() 返回类型为“NoneType”的非迭代器

问题描述 投票:0回答:2

我正在尝试学习 __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)

您能解释一下原因吗?谢谢!

python iteration
2个回答
6
投票

(抱歉,在我急于提供答案时,我没有解释为什么会出现错误。此编辑是为了包括解释。)

说明:

TypeError: iter() returned non-iterator of type 'NoneType'
意味着
__iter__()
没有返回任何值(默认情况下,这意味着“无返回值”(在本例中)为 None)。 (令人困惑,我知道这意味着它在技术上返回 None。)

__iter__
每次从函数内“生成”一个值时都必须返回一个值。如果它不返回值,您会收到错误。

请注意,当我说

return a value
时,你不会使用
return
。对于 iter(基本上是一个生成器函数),您需要使用
yield
。如果您对此感到困惑,请阅读什么是生成器。即位于 https://www.geeksforgeeks.org/generators-in-python/ (例如,不隶属于此链接)。

所以...

两个问题加一项更改(按照@DanielWalker 的建议):

  1. 您可以通过更改使其变得更简单:
   i = i + 10

   i += 10
  1. 您需要改变您的
    print(i for i in my_iter)

照此打印生成器签名。你想要的是:

   print(list(i for i in my_iter))
  1. 您需要在
    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]

1
投票

简而言之,您可能忘记了

return
关键字,或者您调用的方法实际上返回了
None
__iter__
应该返回一个可迭代对象。

def __iter__(self):
    return iter(self._internal_dict)

使用不同的方法返回生成器:

def generator(self):
    for item in self._internal_dict.items()
        yield item
© www.soinside.com 2019 - 2024. All rights reserved.