如何正确输入装饰器和装饰函数?
How to properly type decorator and decorated function?
我有一个装饰器可以捕获请求中的错误:
def catch_request_errors(func):
@functools.wraps(func)
def inner_function(*args, **kwargs): # -> Optional[Dict]
try:
response = func(*args, **kwargs)
except Exception as e:
capture_message(str(e), level='error')
errors = {'error': str(e)}
return errors
if not response.ok:
capture_message(response.text, level='error')
errors = {'error': str(response.text)}
return errors
return None
return inner_function
装饰器本身 returns Optional[Dict] - 发生错误时应该 return {'error': 'error_msg_here' } 或 None 如果没有错误。
这是我的装饰函数,实际上 returns Response 没有装饰器,但是有装饰器 returns Optional[字典]:
@catch_request_errors
def make_request(self, url: str, data: Dict): # -> Optional[Dict]
return requests.post(url, data) # but there is actually -> Response
我不得不像那样“硬打字”来欺骗我的 IDE,但我应该如何正确地打字?
request_errors = self.make_request(settings.DOCUMENT_GENERATOR_URL, data) # type: Optional[Dict]
有点类似于subprocess.Popen.comunicate
中的解决方案
def catch_request_errors(func):
@functools.wraps(func)
def inner_function(*args, **kwargs):
response = None
errors = None
try:
response = func(*args, **kwargs)
except Exception as e:
capture_message(str(e), level='error')
errors = {'error': str(e)}
if response is not None and not response.ok:
capture_message(response.text, level='error')
errors = {'error': str(response.text)}
return response, errors
return inner_function
@catch_request_errors
def make_request(self, url, data):
return requests.post(url, data)
response, errors = make_request(URL, DATA)
if errors is not None:
# handle errors
else:
# code ...
如果有人遇到类似问题,我会发布我的解决方案,感谢@woblob
装饰者:
def catch_request_errors(func: Callable[[str, Dict], Response]) -> Callable[[Tuple[Any], Dict[str, Any]],
Tuple[Response, Optional[Dict]]]:
@functools.wraps(func)
def inner_function(*args, **kwargs) -> Tuple[Response, Optional[Dict]]:
response = None
errors = None
try:
response = func(*args, **kwargs)
except Exception as e:
capture_message(str(e), level='error')
errors = {'error': str(e)}
if response and not response.ok:
capture_message(response.text, level='error')
errors = {'error': str(response.text)}
return response, errors
return inner_function
@catch_request_errors
def make_request(self, url: str, data: Dict) -> Response:
return requests.post(url, data)
response, errors = self.make_request(settings.DOCUMENT_GENERATOR_URL, data)
我有一个装饰器可以捕获请求中的错误:
def catch_request_errors(func):
@functools.wraps(func)
def inner_function(*args, **kwargs): # -> Optional[Dict]
try:
response = func(*args, **kwargs)
except Exception as e:
capture_message(str(e), level='error')
errors = {'error': str(e)}
return errors
if not response.ok:
capture_message(response.text, level='error')
errors = {'error': str(response.text)}
return errors
return None
return inner_function
装饰器本身 returns Optional[Dict] - 发生错误时应该 return {'error': 'error_msg_here' } 或 None 如果没有错误。
这是我的装饰函数,实际上 returns Response 没有装饰器,但是有装饰器 returns Optional[字典]:
@catch_request_errors
def make_request(self, url: str, data: Dict): # -> Optional[Dict]
return requests.post(url, data) # but there is actually -> Response
我不得不像那样“硬打字”来欺骗我的 IDE,但我应该如何正确地打字?
request_errors = self.make_request(settings.DOCUMENT_GENERATOR_URL, data) # type: Optional[Dict]
有点类似于subprocess.Popen.comunicate
中的解决方案def catch_request_errors(func):
@functools.wraps(func)
def inner_function(*args, **kwargs):
response = None
errors = None
try:
response = func(*args, **kwargs)
except Exception as e:
capture_message(str(e), level='error')
errors = {'error': str(e)}
if response is not None and not response.ok:
capture_message(response.text, level='error')
errors = {'error': str(response.text)}
return response, errors
return inner_function
@catch_request_errors
def make_request(self, url, data):
return requests.post(url, data)
response, errors = make_request(URL, DATA)
if errors is not None:
# handle errors
else:
# code ...
如果有人遇到类似问题,我会发布我的解决方案,感谢@woblob
装饰者:
def catch_request_errors(func: Callable[[str, Dict], Response]) -> Callable[[Tuple[Any], Dict[str, Any]],
Tuple[Response, Optional[Dict]]]:
@functools.wraps(func)
def inner_function(*args, **kwargs) -> Tuple[Response, Optional[Dict]]:
response = None
errors = None
try:
response = func(*args, **kwargs)
except Exception as e:
capture_message(str(e), level='error')
errors = {'error': str(e)}
if response and not response.ok:
capture_message(response.text, level='error')
errors = {'error': str(response.text)}
return response, errors
return inner_function
@catch_request_errors
def make_request(self, url: str, data: Dict) -> Response:
return requests.post(url, data)
response, errors = self.make_request(settings.DOCUMENT_GENERATOR_URL, data)