Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/283.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用mypy时在python中正确键入异常/错误元组_Python_Python 3.x_Exception_Typing_Mypy - Fatal编程技术网

使用mypy时在python中正确键入异常/错误元组

使用mypy时在python中正确键入异常/错误元组,python,python-3.x,exception,typing,mypy,Python,Python 3.x,Exception,Typing,Mypy,我已经编写了自己的decoratoradd_warning,以便在出现某些错误时打印costom错误消息。装饰器接收一条消息以及打印此消息的错误类型。我还想将键入添加到此装饰器,并使用mypy检查它。当我使用键入[Exception]时,如果我只是抛出一个普通的异常,那么这种方法很有效。但是,mypy在我使用其他错误,如OSError或AttributeError时会抱怨说: 错误:“添加警告”的参数“errors”具有不兼容的类型“Tuple[type[OSError],type[Attrib

我已经编写了自己的decorator
add_warning
,以便在出现某些错误时打印costom错误消息。装饰器接收一条消息以及打印此消息的错误类型。我还想将键入添加到此装饰器,并使用
mypy
检查它。当我使用
键入[Exception]
时,如果我只是抛出一个普通的
异常,那么这种方法很有效。但是,
mypy
在我使用其他错误,如
OSError
AttributeError
时会抱怨说:

错误:“添加警告”的参数“errors”具有不兼容的类型“Tuple[type[OSError],type[AttributeError]”;应为“Union[str,Type[Exception],Tuple[Type[Any]]”

有人知道有没有比在这里使用
Any
Tuple[Type[OSError],Type[AttributeError]]
更好的方法?具体来说,对于所有Python错误是否有更通用的类型

代码如下:

from functools import wraps
from typing import Union, Tuple, Callable, Type


def add_warning(message: str, flag: str = 'Info',
                errors: Union[str, Type[Exception], Tuple[Type[Exception]]] = 'all') -> Callable:
    """
    Add a warning message to a function, when certain error types occur.
    """
    if errors == 'all':
        errors = Exception

    def decorate(func: Callable):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                result = func(*args, **kwargs)
            except errors:
                warn(message, flag)
                return []
            else:
                return result
        return wrapper
    return decorate


def warn(message: str, flag: str = 'Info') -> None:
    """Print the colored warning message."""
    print(f"{flag}: {message}")


if __name__ == '__main__':

    @add_warning('This is another test warning.', flag='Error')
    def test_func1():
        raise Exception

    @add_warning('This is a test warning.', flag='Error', errors=(OSError, AttributeError))
    def test_func2():
        raise OSError

    test_func1()
    test_func2()

问题在于,
Tuple[Type[Exception]
表示具有单个值的元组。您需要一个大小可变的元组,因此请使用省略号:
Tuple[Type[Exception],…]
以下操作不会引起mypy的抱怨:

from functools import wraps
from typing import Union, Tuple, Callable, Type


def add_warning(message: str, flag: str = 'Info',
                errors: Union[str, Type[Exception], Tuple[Type[Exception], ...]] = 'all') -> Callable:
    """
    Add a warning message to a function, when certain error types occur.
    """
    if errors == 'all':
        errors = Exception

    def decorate(func: Callable):
        @wraps(func)
        def wrapper(*args, **kwargs):
            try:
                result = func(*args, **kwargs)
            except errors:
                warn(message, flag)
                return []
            else:
                return result
        return wrapper
    return decorate


def warn(message: str, flag: str = 'Info') -> None:
    """Print the colored warning message."""
    print(f"{flag}: {message}")


if __name__ == '__main__':

    @add_warning('This is another test warning.', flag='Error')
    def test_func1():
        raise Exception

    @add_warning('This is a test warning.', flag='Error', errors=(OSError, AttributeError))
    def test_func2():
        raise OSError

    test_func1()
    test_func2()