在我的程序中,我有一个函数可以处理 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
虽然我不认为这本身是错误的,因为 getFromAPI
在很多函数中使用,不得不不断重复 try except 语句感觉不对,好像它应该在内部处理函数 getFromAPI
。但是,由于其他 functionone
到 function_n
都根据是否引发错误返回不同的东西,我看不到从 getFromAPI 中处理该问题的方法
,除非有办法让 getFromAPI
强制其父函数返回,而无需在父函数中显式调用 return。
如果做不到这一点,是否有更好的实现我正在尝试做的事情,或者我注定要不断重复 try except 语句?
最佳答案
像这样写一个装饰器
def catchAPIException(func):
def wrapper(*args, **kwargs)
try:
return func(*args, **kwargs)
except getFromAPIException as e:
return handleException(e)
return wrapper
然后你的 functionone
等看起来就像
@catchAPIException
def functionone():
...
data = getFromAPI(url)
...
# formatting data specific to functionone
return formatted_data
但是您想要引发一个非常具体的自定义异常,以便您的装饰器只捕获相关异常。或者,也许您应该创建一些可以以不同方式处理的不同异常。
如果不同的函数想要以自定义的方式格式化异常,装饰器可以传递给另一个实际用于格式化它的函数。 IE。使 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
然后像这样声明对默认异常处理程序满意的函数:
@catchAPIException
def function1():
...
其他有更具体需求的人可以这样做:
def customExceptionHandler(e):
...
@catchAPIException(customExceptionHandler)
def function2():
...
如果您不熟悉装饰器,这里有一个 reasonable tutorial还有 Python 文档,尽管它们没有明确的部分。
关于Python:有没有办法强制父函数返回?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29419121/