python正在处理中_python-处理在gen中引发的异常

我已经需要解决几次这个问题,并且在寻找其他人做了什么之后才提出这个问题。

投掷而不是提高

一个选项(需要一点点重构)是handler()生成器中的异常(另一个错误处理生成器),而不是raise。 这是可能的样子:

def read(handler):

# the handler argument fixes errors/problems separately

while something():

try:

yield something_else()

except Exception as e:

handler.throw(e)

handler.close()

def err_handler():

# a generator for processing errors

while True:

try:

yield

except Exception1:

handle_exc1()

except Exception2:

handle_exc2()

except Exception3:

handle_exc3()

except Exception:

raise

def process():

handler = err_handler()

handler.send(None) # initialize error handler

for item in read(handler):

do stuff

这并不总是最好的解决方案,但肯定是一种选择。

广义解

您可以使用装饰器使一切变得更好:

class MyError(Exception):

pass

def handled(handler):

"""

A decorator that applies error handling to a generator.

The handler argument received errors to be handled.

Example usage:

@handled(err_handler())

def gen_function():

yield the_things()

"""

def handled_inner(gen_f):

def wrapper(*args, **kwargs):

g = gen_f(*args, **kwargs)

while True:

try:

g_next = next(g)

except StopIteration:

break

if isinstance(g_next, Exception):

handler.throw(g_next)

else:

yield g_next

return wrapper

handler.send(None) # initialize handler

return handled_inner

def my_err_handler():

while True:

try:

yield

except MyError:

print("error handled")

# all other errors will bubble up here

@handled(my_err_handler())

def read():

i = 0

while i<10:

try:

yield i

i += 1

if i == 3:

raise MyError()

except Exception as e:

# prevent the generator from closing after an Exception

yield e

def process():

for item in read():

print(item)

if __name__=="__main__":

process()

输出:

0

1

2

error handled

3

4

5

6

7

8

9

但是,这样做的缺点是,您仍然必须将通用handler()处理程序放在可能会产生错误的生成器内部。 解决这个问题是不可能的,因为在生成器中引发任何异常都会将其关闭。

一个想法的核心

最好有某种handler()语句,该语句允许生成器在引发错误后继续运行。 然后,您可以编写如下代码:

@handled(my_err_handler())

def read():

i = 0

while i<10:

yield i

i += 1

if i == 3:

yield raise MyError()

...和handler()装饰器可能看起来像这样:

def handled(handler):

def handled_inner(gen_f):

def wrapper(*args, **kwargs):

g = gen_f(*args, **kwargs)

while True:

try:

g_next = next(g)

except StopIteration:

break

except Exception as e:

handler.throw(e)

else:

yield g_next

return wrapper

handler.send(None) # initialize handler

return handled_inner

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值