使用装饰器进行mypy类型检查

时间:2016-05-07 06:31:28

标签: python-2.7 python-3.x typechecking static-typing mypy

我有以下内容:

在myfile.py中:

from file1 import REQ
@has_request_variable
def fun(request, REQ(validator=check_int))
   /* body */

在file1.py

class REQ(object):
    def __init__(self, validator=None):
        self.validator = validator

def has_request_variables(view_func):
       /* body */
       # Below I am calling the validator function to check
       error = param.validator(var_name, val)

现在我想使用mypy注释有趣的功能,我已经按照以下方式完成了它并且它有效但它不是很理想,因为我很有趣 message的类型为int,所以我们应该用int之类的东西来注释参数...如何使用mypy来实现它。

from file1 import REQ
@has_request_variable
def fun(request, message=REQ(validator=check_int))
    # type(Any, REQ) -> Any
    msg = message # type: int
   /* body */

1 个答案:

答案 0 :(得分:0)

首先,mypy与类型注释没有直接关系。您可以在不注释代码的情况下使用mypy,因为mypy是一个使用类型推断(并键入注释,如果存在)来编写代码的程序。此外,您可以使用不带mypy的类型注释 - 用于许多有用的目的,如文档,代码可读性等。

其次,mypy是一个静态类型检查器。你的程序没有在检查类型时运行,所以没有必要尝试用mypy进行运行时类型检查(这就是我在你的代码中看到的问题)。

因此,如果您想要静态类型检查,请使用注释。但是,如果你想在运行时检查类型,你可以例如使用断言。或者你可以使用它们......

类型注释(使用mypy进行静态类型检查):

根据the PEP,输入注释可以使用以下代码:

def print_many(what, how_many=10):
    long_what = how_many * what
    print(long_what)

对此,您可以获得函数参数,返回类型以及注释的任何局部变量:

def print_many(what: str, how_many: int=10) -> None:
    long_what = how_many * what # type: str
    print(long_what)

对于您的特定用例,如果您知道message属于int类型,那么:def fun(request, message: int)就可以胜任。

您可以在带注释的代码上运行mypy并获取结果,但您的代码将仅进行类型检查,不会被执行。因此,mypy完全忽略了参数的默认值,例如REQ(validator=check_int)

请记住,即使PEP 0484和typing模块是Python 3.5的官方部分,mypy也是一个单独的项目,在许多情况下已经运行良好,但仍处于开发阶段。

运行时类型检查的

断言:

def fun(request, message: int):
    assert isinstance(message, int)
    # function body

mypy会忽略这样的断言,但会在执行函数时检查它。