当一个函数有空yield
语句时,该函数只会None
在第一次迭代时返回,因此您可以说该函数充当只能迭代一次并产生 None 值的生成器:
def foo():
yield
>>> f = foo()
>>> print(next(f))
None
>>> print(next(f))
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
这就是空的yield
作用。但是当一个函数在两个代码块之间有空yield
时,它将yield
在第一次迭代时执行之前的代码,而yield
在第二次迭代时将执行之后的代码:
def foo():
print('--statement before yield--')
yield
print('--statement after yield--')
>>> f = foo()
>>> next(f)
--statement before yield--
>>> next(f)
--statement after yield--
Traceback (most recent call last):
File "<input>", line 1, in <module>
StopIteration
因此,它以某种方式允许您在中间暂停函数的执行,但是,它会StopIteration
为第二次迭代抛出异常,因为该函数实际上在第二次迭代中没有yield
任何作用,为避免这种情况,您可以将默认值传递给next
功能:
查看您的代码,您的函数也在做同样的事情
def draw_ui(self, graphics):
self._reset_components()
imgui.set_next_window_size(200, 200, imgui.ONCE)
if imgui.begin("Entity"):
if not self._selected:
imgui.text("No entity selected")
else:
imgui.text(self._selected.name)
yield #<--------------
imgui.end() #
因此,在调用 funcitondraw_ui
时,如果控制转到else
块,则在 else 块之外的行,即imgui.end()
直到第二次迭代才被调用。
这种类型的实现通常在 ContextManager 中使用,您可以参考从contextlib.contextmanager 文档复制的以下代码片段
from contextlib import contextmanager
@contextmanager
def managed_resource(*args, **kwds):
# Code to acquire resource, e.g.:
resource = acquire_resource(*args, **kwds)
try:
yield resource
finally:
# Code to release resource, e.g.:
release_resource(resource)
>>> with managed_resource(timeout=3600) as resource:
... # Resource is released at the end of this block,
... # even if code in the block raises an exception