我对Python 3.3中的以下内容感到困惑:
>>> def foo(gen=False):
... if not gen:
... return list(range(10))
... else:
... for i in range(10):
... yield i
...
>>> foo()
<generator object foo at 0xb72a016c>
>>> foo(gen=False)
<generator object foo at 0xb72a0144>
>>> foo(gen=True)
<generator object foo at 0xb72a089c>
>>>
我误解了什么?如果gen
为False,则默认值为not gen
,True
为[0,1,2,3,4,5,6,7,8,9]
,因此我应该得到一个整数列表True
。另一方面,如果是(not gen) == False
,则不应 scanf ("%s", a);
导致生成器?
答案 0 :(得分:3)
在函数中包含yield
使其成为生成器函数:当您执行函数时,您将获得一个生成器;没有其他执行发生。只有当生成器开始被要求输入元素时,函数本身才开始执行。
def not_a_generator():
print(1)
print(2)
not_a_generator()
# => 1
# 2
def is_a_generator():
print(1)
yield 7
print(2)
is_a_generator()
# => <generator object bar at 0x10e1471a8>
list(is_a_generator())
# => 1
# 2
# [7]
答案 1 :(得分:1)
将yield
语句放在if
分支中并不重要。 documentation说:
在函数定义中使用yield足以使该定义创建生成器函数而不是正常函数。
但是,您可以通过简单地定义内部生成器函数来实现您的预期目标:
>>> def foo(gen=False):
... if not gen:
... return list(range(10))
... else:
... def foo(): # the inner generator
... for i in range(10):
... yield i
... return foo()
>>> foo()
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> foo(gen=False)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> foo(gen=True)
<generator object foo.<locals>.foo at 0x7f350c7563b8>
>>> g = foo(gen=True)
>>> next(g)
0
这一次,yield
语句将内部foo
转换为生成器。外foo
仍然是正常函数。