提问人:zsepi 提问时间:11/10/2023 最后编辑:zsepi 更新时间:11/15/2023 访问量:41
为什么 GeneratorExit 是由 yield 和 exception 的组合引发的,抑制 ContextDecorator?
why is GeneratorExit raised by this combination of yield & exception suppressing ContextDecorator?
问:
我的目标是,而不是写作
for item in items:
with MyCD():
... # processing logic
我想要一行
for item in MyCD.yield_each_item_wrapped(items):
... # processing logic
但是,尽管我通过错误返回来抑制错误,但在引发错误的项目之后,它会立即获得 .ContextDecorator
True
__exit__
yield
GeneratorError
因此,尽管已经处理了引发的异常,但似乎调用了生成器。.close()
我正在运行 python 3.11.4
我本来希望继续处理剩下的两个项目,因为我故意禁止了引发的异常,即:如下面的代码片段所示
def yield2(items):
for i, item in enumerate(items):
with MyCD():
if item:
raise Exception("my error")
yield i # yield success
if __name__ == "__main__":
raising_flags = [True, False, False, True]
expected = [1, 2]
actual = [i for i in yield2(raising_flags)]
assert expected == actual, (expected, actual)
import traceback
from contextlib import ContextDecorator
class MyCD(ContextDecorator):
@classmethod
def yield_each_item_wrapped(cls, items, **kwargs):
for i, item in enumerate(items):
print(f"yield_each_item_wrapped {i=}")
print(f"yield_each_item_wrapped {item=}")
with cls(**kwargs):
yield item
def __enter__(self):
print("__enter__")
def __exit__(self, exc_type, exc, exc_tb):
print("__exit__")
if exc:
traceback.print_exc()
return True # do not propagate
if __name__ == "__main__":
raising_flags = [True, False, False, True]
expected = [1, 2]
actual = []
for i, raising in enumerate(MyCD.yield_each_item_wrapped(raising_flags)):
if raising:
raise Exception("my error")
actual.append(i)
assert expected == actual, (expected, actual)
生产
yield_each_item_wrapped i=0
yield_each_item_wrapped item=True
__enter__
__exit__
Traceback (most recent call last):
File "x.py", line 12, in yield_each_item_wrapped
yield item
GeneratorExit
yield_each_item_wrapped i=1
yield_each_item_wrapped item=False
__enter__
Exception ignored in: <generator object MyCD.yield_each_item_wrapped at 0x7f42e625aac0>
Traceback (most recent call last):
File "x.py", line 30, in <module>
raise Exception("my error")
RuntimeError: generator ignored GeneratorExit
Traceback (most recent call last):
File "x.py", line 30, in <module>
raise Exception("my error")
Exception: my error
答: 暂无答案
评论
for
with
.close
.close
被调用]不是。链接问题中的答案解释了原因。