我用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] 删除。
我来说两句