Python 进入时回报和收益的不同行为;加上;陈述
当我创建一个支持范围为的Python 进入时回报和收益的不同行为;加上;陈述,python,Python,当我创建一个支持范围为的类时,当我在\uuuuuu enter\uuuuu方法中使用yield和return作为最后调用时,我会得到不同的、无法解释的行为,代码: class TestWith: def __init__(self, val): self.val=val def __enter__(self): print("Entered!") yield # return def
类时,当我在\uuuuuu enter\uuuuu
方法中使用yield和return作为最后调用时,我会得到不同的、无法解释的行为,代码:
class TestWith:
def __init__(self, val):
self.val=val
def __enter__(self):
print("Entered!")
yield
# return
def __exit__(self, exc_type, exc_val, exc_tb):
print(f"In exit:, type: {exc_type}, val: {exc_val}, tb: {exc_tb}")
with TestWith(4):
print("printme")
输出为:
printme
In exit:, type: None, val: None, tb: None
i、 e.“已输入!”未打印,将\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
def __enter__(self):
print("Entered!")
# yield
return
结果:
Entered!
printme
In exit:, type: None, val: None, tb: None
为什么这两种实现有不同的行为?此外,我还可以想象,“Entered!”无论如何都会被打印出来,因为它是在return/yield之前调用的。您可能会混淆用于创建上下文管理器的“yield语法”(addind,支持函数而不需要创建类)
从contextlib导入contextmanager
@上下文管理器
def TestWith(val):
打印(“已输入!”)
产量
打印(“退出”)
使用TestWith(4):
打印(“打印我”)
输出:
Entered!
printme
Exit
在函数定义中使用yield
,函数将成为生成器,其工作方式完全不同。下面是一个例子:
>>> def func1():
... print('hi')
... yield
...
>>> def func2():
... print('hi')
... return
...
>>> func1() # returns a generator...doesn't execute the function!
<generator object func1 at 0x000002555B088510>
>>> func2()
hi
>>> g=func1() # save the generator
>>> next(g) # execute it to the next yield
hi
>>> next(g) # No more yields throws an exception
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>def func1():
... 打印('hi')
... 产量
...
>>>def func2():
... 打印('hi')
... 返回
...
>>>func1()#返回一个生成器…不执行该函数!
>>>func2()
你好
>>>g=func1()#保存生成器
>>>next(g)#执行到下一个收益率
你好
>>>下一步(g)#没有更多收益抛出异常
回溯(最近一次呼叫最后一次):
文件“”,第1行,在
停止迭代
\uuuu enter\uuuu
是一个普通函数,而不是生成器,所以在这种情况下不要使用yield
。好吧,yield
和return
做不同的事情,那么为什么你认为它们都应该在这里工作呢?@KonradRudolph他们是。它们如何影响在实际调用之前发生的函数调用?因为return
和yield
不是函数调用。它们是控制流语句,这意味着它们控制整个函数的行为。在yield
的特定情况下,它的使用导致函数具有完全不同的语义,包括不同的返回值和不同的语句序列。这与上下文管理器无关,这只会使示例变得复杂。问题基本上是“什么是生成器函数”。事实上,上下文管理器的使用让我想到了这个奇怪的场景,但它并没有真正回答这个问题。谢谢你的例子