【发布时间】:2018-12-18 16:05:21
【问题描述】:
我以 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__ 函数的存在是不够的。
【问题讨论】:
-
Magicmethods 只有在它们是类属性时才会被调用——你不能将它们设置为实例属性(你可以但是它们不会被调用
)。 -
感谢 bruno 的回答 +1。
-
您错过了最简单的方法,即使用内置工具生成无限序列:
squares = map(lambda x: x*x, itertools.count())或squares = (x*x for x in itertools.count())。使用islice获取序列的有限前缀:list(itertools.islice(squares, 5)) == [0,1,4,9,16]
标签: python python-3.x