如何正确键入装饰器和装饰函数?

问题描述

我有一个装饰器,应该从请求中捕获错误:

android {
    compileSdkVersion 28

    ... 
    buildTypes {
        release {
            shrinkResources false
            minifyEnabled false
            signingConfig signingConfigs.release
            
        }
    }
}

装饰器本身返回 Optional [Dict] -发生错误时应返回{'error':'error_msg_here'}或无错误时返回None。

这是我的修饰函数,它实际上返回 Response (不响应),而没有修饰符,则返回 Optional [Dict]

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

我必须像这样的“硬类型”才能使我的IDE更加稳定,但是我应该如何正确地做到呢?

@catch_request_errors
def make_request(self,url: str,data: Dict): # -> Optional[Dict]
    return requests.post(url,data)  # but there is actually -> Response

解决方法

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,level='error')
            errors = {'error': str(e)}

        if response and not response.ok:
            capture_message(response.text,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)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...