Python可迭代协议

Tkircsi

我用4种方法制作了一个可迭代的Squares对象。经典的类,生成器样式以及有趣的是闭包样式和改进的(?)闭包样式。

class Squares:
    def __init__(self, n):
        self.n = n

    def __iter__(self):
        return self.SquaresIterator(self.n)

    class SquaresIterator:
        def __init__(self, n):
            self.n = n
            self.i = 0

        def __iter__(self):
            return self

        def __next__(self):
            if self.i >= self.n:
                raise StopIteration

            result = self.i ** 2
            self.i += 1
            return result

它按预期工作

sq_class = Squares(5)
list(sq_class)
[0, 1, 4, 9, 16]
# calling again will create a new iterator
list(sq_class)
[0, 1, 4, 9, 16]

发电机

def squares(n):
    for i in range(n):
        yield i ** 2

sq_gen = squares(5)
list(sq_gen)
[0, 1, 4, 9, 16]
# calling again will return empty [] is OK, generator exhausted.
list(sq_gen)
[]

关闭

def Squares(n):
    def inner():
        return squares_gen(n)

    def squares_gen(n):
        for i in range(n):
            yield i ** 2

    return inner

sq_closure = Squares(5)
list(sq_closure())
[0, 1, 4, 9, 16]
# calling again the inner will create a new generator so it is not exhausted
list(sq_closure())
[0, 1, 4, 9, 16]

改进的(?)关闭

def Squares(n):
    def inner():
        return squares_gen(n)

    def squares_gen(n):
        for i in range(n):
            yield i ** 2

    inner.__iter__ = lambda : squares_gen(n)
    return inner

sq_closure = Squares(5)
list(sq_closure)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-13-beb02e61ccfb> in <module>
----> 1 for i in sq:
      2     print(i)

TypeError: 'function' object is not iterable

我想尝试的是将__iter__函数附加到内部函数对象上并返回一个生成器,然后我可以离开()-s并将返回的内部函数用作可迭代对象。可迭代协议的确切定义是什么?看起来,仅__iter__功能的存在是不够的。

布鲁诺·德斯胡里尔斯

文档中的“可迭代协议的确切定义”

可迭代:一个对象,一次可以返回其成员。可迭代的示例包括您使用__iter__()方法或__getitem__()实现序列语义方法定义的任何类的(...)对象

但是:__magicmethods__在类中定义时,才会调用-你不能覆盖对每个实例的基础上(也可以,但他们将不会被调用)。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章