从用户代码中引发的异常触发生成器中的 except 子句
Trigger except clause in generator from exception raised in user code
我有一系列嵌套的生成器,如果用户代码中发生异常,我想从第一个生成器知道,为了举例,考虑下面的代码:
#############################################################################
def generator():
try:
for i in (1, 2, 3, 4, 5, 6):
print(f"Generator: {i}.")
yield i
except:
print("Exception handled in generator")
raise
#############################################################################
def intermediary_generator():
try:
gen = generator()
while i := gen.send(None):
print(f"Intermediary generator: {i}.")
yield i
except StopIteration:
pass
except:
print ("Exception handled in intermediary generator")
raise
############################################################################
user_code_generator = intermediary_generator()
try:
while i := user_code_generator.send(None):
print(f"User code generator: {i}.")
if i == 4:
raise Exception("The exception in the user code")
except StopIteration:
pass
except:
print("Exception handled in user code generator")
raise
我需要用户代码中的异常向下传播到中间生成器和主生成器,我期望根据打印语句出现以下顺序:
Exception handled in generator
Exception handled in intermediary generator
Exception handled in user code generator
但是如果我执行上面的代码,我没有看到在生成器或中间生成器中处理的异常。
我想我会回答我自己的问题,生成器的 throw 方法正是我需要的,它将用户代码中的异常传播到主生成器。
#############################################################################
def generator():
try:
for i in (1, 2, 3, 4, 5, 6):
print(f"Generator: {i}.")
yield i
except:
print("Exception handled in generator")
raise
#############################################################################
def intermediary_generator():
try:
gen = generator()
while i := gen.send(None):
print(f"Intermediary generator: {i}.")
yield i
except StopIteration:
print("Stop iteration in intermediary generator")
except Exception as exc:
print ("Exception handled in intermediary generator")
gen.throw(exc)
raise
############################################################################
user_code_generator = intermediary_generator()
try:
while i := user_code_generator.send(None):
print(f"User code generator: {i}.")
if i == 4:
raise Exception("The exception in the user code")
except StopIteration:
pass
except Exception as exc:
print("Exception handled in user code generator")
user_code_generator.throw(exc)
raise
并且输出:
Generator: 1.
Intermediary generator: 1.
User code generator: 1.
Generator: 2.
Intermediary generator: 2.
User code generator: 2.
Generator: 3.
Intermediary generator: 3.
User code generator: 3.
Generator: 4.
Intermediary generator: 4.
User code generator: 4.
Exception handled in user code generator
Exception handled in intermediary generator
Exception handled in generator
Traceback (most recent call last):
File "<string>", line 39, in <module>
File "<string>", line 25, in intermediary_generator
File "<string>", line 9, in generator
File "<string>", line 20, in intermediary_generator
File "<string>", line 34, in <module>
Exception: The exception in the user code
我有一系列嵌套的生成器,如果用户代码中发生异常,我想从第一个生成器知道,为了举例,考虑下面的代码:
#############################################################################
def generator():
try:
for i in (1, 2, 3, 4, 5, 6):
print(f"Generator: {i}.")
yield i
except:
print("Exception handled in generator")
raise
#############################################################################
def intermediary_generator():
try:
gen = generator()
while i := gen.send(None):
print(f"Intermediary generator: {i}.")
yield i
except StopIteration:
pass
except:
print ("Exception handled in intermediary generator")
raise
############################################################################
user_code_generator = intermediary_generator()
try:
while i := user_code_generator.send(None):
print(f"User code generator: {i}.")
if i == 4:
raise Exception("The exception in the user code")
except StopIteration:
pass
except:
print("Exception handled in user code generator")
raise
我需要用户代码中的异常向下传播到中间生成器和主生成器,我期望根据打印语句出现以下顺序:
Exception handled in generator
Exception handled in intermediary generator
Exception handled in user code generator
但是如果我执行上面的代码,我没有看到在生成器或中间生成器中处理的异常。
我想我会回答我自己的问题,生成器的 throw 方法正是我需要的,它将用户代码中的异常传播到主生成器。
#############################################################################
def generator():
try:
for i in (1, 2, 3, 4, 5, 6):
print(f"Generator: {i}.")
yield i
except:
print("Exception handled in generator")
raise
#############################################################################
def intermediary_generator():
try:
gen = generator()
while i := gen.send(None):
print(f"Intermediary generator: {i}.")
yield i
except StopIteration:
print("Stop iteration in intermediary generator")
except Exception as exc:
print ("Exception handled in intermediary generator")
gen.throw(exc)
raise
############################################################################
user_code_generator = intermediary_generator()
try:
while i := user_code_generator.send(None):
print(f"User code generator: {i}.")
if i == 4:
raise Exception("The exception in the user code")
except StopIteration:
pass
except Exception as exc:
print("Exception handled in user code generator")
user_code_generator.throw(exc)
raise
并且输出:
Generator: 1.
Intermediary generator: 1.
User code generator: 1.
Generator: 2.
Intermediary generator: 2.
User code generator: 2.
Generator: 3.
Intermediary generator: 3.
User code generator: 3.
Generator: 4.
Intermediary generator: 4.
User code generator: 4.
Exception handled in user code generator
Exception handled in intermediary generator
Exception handled in generator
Traceback (most recent call last):
File "<string>", line 39, in <module>
File "<string>", line 25, in intermediary_generator
File "<string>", line 9, in generator
File "<string>", line 20, in intermediary_generator
File "<string>", line 34, in <module>
Exception: The exception in the user code