Python 从iter返回一个非迭代器__

Python 从iter返回一个非迭代器__,python,Python,为什么这会提供回溯 class test(object): def __init__(self): pass def __iter__(self): return "my string" o = test() print iter(o) $python iter\u implement.py 回溯(最近一次呼叫最后一次): 文件“iter_implement.py”,第9行,在 印刷iter(o) TypeError:iter()返回了“str

为什么这会提供回溯

class test(object):
    def __init__(self):
        pass
    def __iter__(self):
        return "my string"

o = test()
print iter(o)
$python iter\u implement.py
回溯(最近一次呼叫最后一次):
文件“iter_implement.py”,第9行,在
印刷iter(o)
TypeError:iter()返回了“str”类型的非迭代器
我希望
\uuu iter\uuu
在本例中只返回字符串。何时以及为什么检测到返回的对象不是迭代器对象?

str
是一个iterable但不是迭代器,细微但重要的区别。请看下面的解释

您希望返回一个对象,其中包含
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

$ python iter_implement.py
Traceback (most recent call last):
  File "iter_implement.py", line 9, in <module>
    print iter(o)
TypeError: iter() returned non-iterator of type 'str'
str
不执行
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

def __iter__(self):
      return iter("my string")
如果没有
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu

您可以使用一个生成器,它本身有一个返回self
\uuuu iter\uuu

In [141]: next(iter(s))
Out[141]: 'm'
或者是一个你自己实现
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu


\uuuu iter\uuuuu
魔术函数的目的是返回可以迭代(例如循环)的内容。最常见的解决方案是返回
iter(something)
其中
something
可以是列表、元组、集合、字典、字符串。。。任何我们可以迭代的东西。看看这个例子:

class test:
    def __init__(self, somestring):
        self.s = iter(somestring)

    def __iter__(self):
        return self

    def __next__(self):
        return next(self.s) ## this exhausts the generator and raises StopIteration when done.

In [3]: s = test('foo')

In [4]: for i in s:
   ...:     print(i)
   ...:
f
o
o
输出:

class Band:
    def __init__(self):
        self.members = []

    def add_member(self, name):
        self.members.append(name)

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

if __name__ == '__main__':
    band = Band()
    band.add_member('Peter')
    band.add_member('Paul')
    band.add_member('Mary')

    # Magic of __iter__:
    for member in band:
        print(member)
在这种情况下,
\uuu iter\uu
魔术功能允许我们在
波段
中循环,就像它是一个成员集合一样。这意味着在您的情况下,返回“我的字符串”将不起作用。如果您想要“我的字符串”中的字符列表:

但是,如果要返回包含单个元素“my string”的列表,则:


回答你的具体问题。Python2将检查是否存在
。下一步
类属性:

def __iter__(self):
    return iter(["my string"])
>类测试(对象):
...     下一个=无
...     定义(自我):
...         回归自我
... 
>>>打印iter(测试())
实例属性无法执行以下操作:

>>> class test(object):
...     next = None
...     def __iter__(self):
...         return self
... 
>>> print iter(test())
<__main__.test object at 0x7fcef75c2f50>
>类测试(对象):
...    定义初始化(自):
...        self.next=无
...    定义(自我):
...        回归自我
... 
>>>打印iter(测试())
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
TypeError:iter()返回类型为“test”的非迭代器

可以通过添加iter()调用来修复代码:

以下是一个运行示例:

class test(object):
    def __init__(self):
        pass
    def __iter__(self):
        return iter("my string")
>o=test()
>>>iter(o)
>>>名单(o)
['m','y','s','t','r','i','n','g']
原始错误的原因是uu iter_uuu的API声称返回实际的迭代器。函数的作用是:检查合同是否履行

注意,这种错误检查也发生在其他地方。例如,len()函数检查以确保_len _;()方法返回整数:

>>> o = test()
>>> iter(o)
<iterator object at 0x106bfa490>
>>> list(o)
['m', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g']
>>A类:
定义(自我):
返回“你好”
>>>len(A())
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
len(A())
TypeError:“str”对象不能解释为整数

问题不是如何修复代码。问题是为什么会出现错误?我知道iterable和iterator之间的区别。@abc很抱歉您知道这一区别,但指出它肯定会让其他人受益。此外,还添加了一个解释。iter()函数检查以确保合同得到履行。。。但不是很彻底;-)好吧,也许足够好去抓到那只奇怪的脚了。很有趣,你和雷蒙德·海廷格一起回答了我的问题。
def __iter__(self):
    return iter(["my string"])
>>> class test(object):
...     next = None
...     def __iter__(self):
...         return self
... 
>>> print iter(test())
<__main__.test object at 0x7fcef75c2f50>
>>> class test(object):
...    def __init__(self):
...        self.next = None
...    def __iter__(self):
...        return self
... 
>>> print iter(test())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iter() returned non-iterator of type 'test'
class test(object):
    def __init__(self):
        pass
    def __iter__(self):
        return iter("my string")
>>> o = test()
>>> iter(o)
<iterator object at 0x106bfa490>
>>> list(o)
['m', 'y', ' ', 's', 't', 'r', 'i', 'n', 'g']
>>> class A:
        def __len__(self):
            return 'hello'

>>> len(A())
Traceback (most recent call last):
  File "<pyshell#4>", line 1, in <module>
    len(A())
TypeError: 'str' object cannot be interpreted as an integer