我有以下mcve:
import logging
class MyGenIt(object):
def __init__(self, name, content):
self.name = name
self.content = content
def __iter__(self):
with self:
for o in self.content:
yield o
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type:
logging.error("Aborted %s", self,
exc_info=(exc_type, exc_value, traceback))
下面是使用示例:
for x in MyGenIt("foo",range(10)):
if x == 5:
raise ValueError("got 5")
我希望
logging.error
报告ValueError
,但它报告GeneratorExit
:ERROR:root:Aborted <__main__.MyGenIt object at 0x10ca8e350>
Traceback (most recent call last):
File "<stdin>", line 8, in __iter__
GeneratorExit
当我在
GeneratorExit
中捕获__iter__
时:def __iter__(self):
with self:
try:
for o in self.content:
yield o
except GeneratorExit:
return
当然不会记录任何内容,因为
__exit__
是用exc_type=None
调用的。为什么我在
GeneratorExit
中看到ValueError
而不是__exit__
?我该怎么做才能获得所需的行为,即
ValueError
中的__exit__
? 最佳答案
简单地说,您可以从生成器中“调出上下文管理器”,只需更改3行即可获得:
import logging
class MyGenIt(object):
def __init__(self, name, content):
self.name = name
self.content = content
def __iter__(self):
for o in self.content:
yield o
def __enter__(self):
return self
def __exit__(self, exc_type, exc_value, traceback):
if exc_type:
logging.error("Aborted %s", self,
exc_info=(exc_type, exc_value, traceback))
with MyGenIt("foo", range(10)) as gen:
for x in gen:
if x == 5:
raise ValueError("got 5")
一个上下文管理器,它还可以充当迭代器——并捕获调用方代码异常,如ValueError。
关于python - 如何使用GeneratorExit?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50691616/