在我的程序中,我有一个处理requests调用的函数,并返回已处理的调用或引发异常.许多其他函数使用此函数,但是,我遇到的问题是如何处理可能引发的异常.目前它设置如此(简化):
def getFromAPI(url):
# create variable headers
r = requests.get(url, headers=headers)
if r.status_code == 404:
raise Exception("Error raised")
else:
#process data
return data
def functionone():
...
try:
data = getFromAPI(url)
except Exception as e:
return handleException(e)
#handles problems, returns exception-formatted data
...
# formatting data specific to functionone
return formatted_data
def functiontwo():
...
try:
data = getFromAPI(url)
except Exception as e:
return handleException(e)
#handles problems, returns exception-formatted data
...
# formatting data specific to functiontwo
return formatted_data
def functionthree():
...
#similar to functionone and functiontwo
Run Code Online (Sandbox Code Playgroud)
虽然我认为这本身并不错,但由于getFromAPI在很多函数中使用,因此不得不经常重复try除了语句错误,就好像它应该在函数内处理一样getFromAPI.但是,由于另一个functionone通过function_n所有返回不同的东西取决于是否引发了错误,我无法看到从内部处理它的方法getFromAPI,除非有一种方法getFromAPI强制它的父函数返回,而不显式调用返回父函数.
如果不这样做,是否有更好的实现我正在尝试做的事情,或者我注定要继续重复尝试除了语句?
写一个这样的装饰器
def catchAPIException(func):
def wrapper(*args, **kwargs)
try:
return func(*args, **kwargs)
except getFromAPIException as e:
return handleException(e)
return wrapper
Run Code Online (Sandbox Code Playgroud)
然后你的functionone等等看起来像
@catchAPIException
def functionone():
...
data = getFromAPI(url)
...
# formatting data specific to functionone
return formatted_data
Run Code Online (Sandbox Code Playgroud)
但是你想要提出一个非常具体的自定义 Exception,这样你的装饰器才会捕获相关的.或许您应该创建一些可以不同方式处理的不同异常.
如果不同的函数想要以自定义方式格式化异常,则装饰器可以传递另一个实际用于格式化它的函数.即做handleException一个参数catchAPIException
def catchAPIException(exceptionHandler = handleException):
def real_decorator(func):
def wrapper(*args, **kwargs)
try:
return func(*args, **kwargs)
except getFromAPIException as e:
return exceptionHandler(e)
return wrapper
return real_decorator
Run Code Online (Sandbox Code Playgroud)
然后,对默认异常处理程序感到满意的函数声明如下:
@catchAPIException
def function1():
...
Run Code Online (Sandbox Code Playgroud)
具有更多特定需求的其他人可以这样做:
def customExceptionHandler(e):
...
@catchAPIException(customExceptionHandler)
def function2():
...
Run Code Online (Sandbox Code Playgroud)
如果你不熟悉装饰器,这里有一个合理的教程,虽然他们没有关于它们的明确部分,但也有Python文档.
| 归档时间: |
|
| 查看次数: |
1611 次 |
| 最近记录: |