理解这个复杂示例的一些要点:
- 3个函数的闭包指向
make_fns_by_...
作用域中相同的i
- 生成器是“懒惰”的,如下面详细解释的那样——它实际上改变了代码调用顺序
def make_fns_by_list():
fns = []
for i in list(range(3)):
def f():
print(i)
print(id(f), f.__closure__, f.__closure__[0].cell_contents)
fns.append(f)
return fns
def make_fns_by_generator():
for i in list(range(3)):
def f():
print(i)
print(id(f), f.__closure__, f.__closure__[0].cell_contents)
yield(f)
def call_fns():
fns = make_fns_by_generator()
fns_iter = iter(fns)
f = next(fns_iter)
print(id(f), f.__closure__, f.__closure__[0].cell_contents, '-->', f())
f = next(fns_iter)
print(id(f), f.__closure__, f.__closure__[0].cell_contents, '-->', f())
f = next(fns_iter)
print(id(f), f.__closure__, f.__closure__[0].cell_contents, '-->', f())
print('-' * 100)
fns = make_fns_by_list()
fns_iter = iter(fns)
f = next(fns_iter)
print(id(f), f.__closure__, f.__closure__[0].cell_contents, '-->', f())
f = next(fns_iter)
print(id(f), f.__closure__, f.__closure__[0].cell_contents, '-->', f())
f = next(fns_iter)
print(id(f), f.__closure__, f.__closure__[0].cell_contents, '-->', f())
def main():
call_fns()
if __name__ == '__main__':
main()