如何使用注释返回多个值?

时间:2015-12-22 19:03:28

标签: python python-3.x annotations

我最近在Python 3.x中发现了Function Annotations以及它们可能具有的实用性。

我安装了模块typeannotations以允许对参数和返回类型进行类型检查。

工作示例:

from annotation.typed import typechecked    

@typechecked
def test_func(arg1: int) -> int:
    return arg1   

print(test_func(1))

>>> 1

破碎的示例,提升TypeError

from annotation.typed import typechecked

@typechecked
def test_func(arg1: int) -> str:
    return arg1   

print(test_func(1))

>>>TypeError: Incorrect return type

但是我无法弄清楚如何使用typechecker来返回多个值

from annotation.typed import typechecked

@typechecked
def test_func(arg1: str, arg2: str) -> (str, str):
    return arg1, arg2

print(test_func('hello', 'world'))

我传递了两个str并返回了一个包含两个str的列表,但是它引发了

TypeError: Incorrect return type

我如何以这种方式返回多个值?

1 个答案:

答案 0 :(得分:1)

简短的回答是

长答案是,有一些编码:

如果您愿意修改源代码(我曾多次必须这样做),您可以实现自己的方式。

请记住,这只是一小段代码,我确信有更有效的方法可以做到这一点,但是这会让你想要的是:

typed.py文件中,找到_check_return_type()功能并将其更改为以下内容:

def _check_return_type(signature, return_value):
    """Check that the return value of a function matches the signature."""
    annotation = signature.return_annotation

    if annotation is EMPTY_ANNOTATION:
        annotation = AnyType

    # If the return type is a tuple of typed values, and the length is greater than 1 (to prevent the actual tuple return type)
    if isinstance(annotation, tuple) and len(annotation) > 1:
        for p, a in zip(return_value, annotation):
            if not isinstance(p, a):
                raise TypeError('Incorrect return type: {} ({} required)'.format(type(p), a))

    else:
        if not isinstance(return_value, annotation):
            raise TypeError('Incorrect return type')
    return return_value

这将按照您设置的元组的顺序检查返回的每个值。

现在,如果您不想修改原始源代码,您可以编写自己的函数并像这样调用它:

def typechecked(target):
    import inspect
    import functools

    @functools.wraps(target)
    def wrapper(*args, **kwargs):
        signature = inspect.signature(target)
        params = target(*args, **kwargs)

        for p, a in zip(params, signature.return_annotation):
            if not isinstance(p, a):
                raise TypeError('Incorrect return type: {} ({} required)'.format(type(p), a))
        return params

    return wrapper

希望这有帮助。