当在Python中的同一函数中使用yield和return时,究竟会发生什么?
def find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1: return
yield start
start += len(sub) # use start += 1 to find overlapping matches
它还是发电机吗?
答案 0 :(得分:55)
是的,它仍然是一个发电机。 return
(几乎)相当于提升StopIteration
。
PEP 255说出来:
规格:退货
生成器函数还可以包含以下形式的返回语句:
"return"
请注意,返回语句中不允许使用expression_list 发电机的主体(当然,它们可能出现在发电机中) 嵌套在发电机内的非发电机功能体。)
当遇到return语句时,控制按任何方式进行 函数返回,执行适当的finally子句(如果有的话) 存在)。然后引发一个StopIteration异常,表示该异常 迭代器已经用尽了。如果是,也会引发StopIteration异常 控制流从发电机的末端流出而没有明确的返回。
请注意,返回意味着“我已经完成了,并没有任何有趣的东西 返回“,用于发电机功能和非发电机功能。
请注意,返回并不总是等同于提升StopIteration: 区别在于try / except结构的封闭程度 对待。例如,
>>> def f1(): ... try: ... return ... except: ... yield 1 >>> print list(f1()) []
因为,就像在任何函数中一样,返回只是退出,但是
>>> def f2(): ... try: ... raise StopIteration ... except: ... yield 42 >>> print list(f2()) [42]
因为StopIteration是由一个裸的“except”捕获的,就像任何一样 异常。
答案 1 :(得分:24)
是的,它仍然是一台发电机。空return
或return None
可用于结束生成器函数。这相当于提高StopIteration
(有关详细信息,请参阅@NPE's answer。)
请注意,在3.3之前的Python版本中,带有非None参数的返回值为SyntaxError
。
正如@BrenBarn在从Python 3.3开始的评论中指出的那样,返回值现在传递给StopIteration.
来自PEP 380:
在生成器中,语句
return value
在语义上等同于
raise StopIteration(value)
答案 2 :(得分:8)
有一种方法可以在函数中实现yield和return方法,该方法允许您返回值或生成器。
它可能不像你想要的那么干净,但它确实能达到预期效果。
以下是一个例子:
def six(how_many=None):
if how_many is None or how_many < 1:
return None # returns value
if how_many == 1:
return 6 # returns value
def iter_func():
for count in range(how_many):
yield 6
return iter_func() # returns generator
答案 3 :(得分:0)
注意:以下示例不会导致StopIteration
异常。
def odd(max):
n = 0
while n < max:
yield n
n = n + 1
return 'done'
for x in odd(3):
print(x)
for
循环将其捕获。那是停止的信号
但是您可以通过以下方式捕获它:
g = odd(3)
while True:
try:
x = next(g)
print(x)
except StopIteration as e:
print("g return value:", e.value)
break