'r = yield n'和'r =(yield n)'有什么区别?

时间:2019-04-09 02:27:15

标签: python python-3.x coroutine

我正在学习协程,并尝试了一些教程,我找到了这段代码。

>>> def g(n):
...     while n >= 0:
...         r = (yield n)
...         if r:
...             n = r
...         else:
...             n -= 1

我问自己为什么会有r = (yield n),然后我修改了如下代码,

>>> def f(n):
...     while n >= 0:
...         r = yield n
...         if r:
...             n = r
...         else:
...             n -= 1
...
>>>

此后,我猜想在调用send(value)时,r = yield n将返回值,而r = (yield n)将返回一个元组,例如(value)。

所以我分别测试了代码,结果是:

>>>
>>> gc = g(5)
>>> gc.send(None)
5
>>> type(gc.send(4))
<class 'int'>
>>>

>>> fc = f(5)
>>> fc.send(None)
5
>>> fc.send(4)
4
>>> type(fc.send(4))
<class 'int'>

两个结果均为“ int”类型,而不是元组类型。 我真的很困惑,这两个代码之间的区别是什么? 似乎根本没有区别。

3 个答案:

答案 0 :(得分:2)

没有区别,您可以直接通过parser进行验证:

>>> source1 = "r = (yield n)"
>>> source2 = "r = yield n"
>>> import ast
>>> ast.dump(ast.parse(source1))
"Module(body=[Assign(targets=[Name(id='r', ctx=Store())], value=Yield(value=Name(id='n', ctx=Load())))])"
>>> ast.dump(ast.parse(source2))
"Module(body=[Assign(targets=[Name(id='r', ctx=Store())], value=Yield(value=Name(id='n', ctx=Load())))])"

通过检查fg的{​​{3}},您也可以以更round回的方式得出相同的结论。

非空元组需要逗号,请参见 disassembly

答案 1 :(得分:1)

  

似乎根本没有区别。

您是对的-完全没有区别。

r = (yield n)分配只是具有一些多余的括号。 就像分配four = 1 + (1 + 1) + 1一样;父母们什么都没做。

如果您想要一个1元组,请使用逗号:

>>> r = 6,
>>> r
(6,)

请随意添加括号,例如(6,), 如果您觉得应该提请注意表达式是元组。

答案 2 :(得分:0)

没有区别。括号告诉解释器首先计算该语句。当解释器读取r = yield n时,它将首先计算yield n,然后将其分配给r。它已经先计算了产量n,因此不需要括号。如果要使其成为一个元组,可以使用此代码r = (yield n,)