我正在阅读输入模块代码,并查看mypy以了解它是如何进行类型检查的.对我来说不幸的是,mypy构建一个非常智能的树,其中包含我仍然不理解的类型表达式,并且它都基于静态分析.
我想在Python中实现一个动态(无静态分析)的类型检查系统.假设调用执行类型检查的函数check_type,我想完成以下操作:
>>> import typing
>>>
>>> check_type(1, int)
True
>>> check_type(1, float)
False
>>> check_type([1], typing.List[int])
True
>>> check_type([1], typing.List[float])
False
>>> check_type([1], typing.List[typing.Any])
True
>>> check_type((1,), typing.Tuple[int])
True
Run Code Online (Sandbox Code Playgroud)
我考虑过从其值重新创建对象类型,例如:
>>> get_type([1])
typing.List<~T>[int]
Run Code Online (Sandbox Code Playgroud)
但这不适用于issubclass:
>>> issubclass(typing.List[int], typing.List[typing.Any])
False
Run Code Online (Sandbox Code Playgroud)
我没有看到在Python中检查类型的简单方法,而没有假设很多关于stdlib模块内部的typing东西(例如,访问__args__或__tuple_params__).
如何正确实现check_type适用于之前列出的案例的功能?我使用的是Python 2.7.
您可以轻松获得非常有限的功能,该功能对于您的问题中提供的简单示例可以正常工作:
import mypy.api
def check_type(value, typ):
program_text = 'from typing import *; v: {} = {}'.format(typ, repr(value))
normal_report, error_report, exit_code = mypy.api.run(['-c', program_text])
return exit_code == 0
int_ = 1
str_ = 'a'
list_str_ = ['a']
list_int_ = [1]
tuple_int_ = (1,)
assert check_type(int_, 'int')
assert not check_type(str_, 'int')
assert check_type(list_int_, 'List[int]')
assert not check_type(list_str_, 'List[int]')
assert check_type(list_int_, 'List[Any]')
assert check_type(tuple_int_, 'Tuple[int]')
Run Code Online (Sandbox Code Playgroud)
您甚至可以通过稍微扩展此代码来执行一些更高级的操作(例如,引用与您在程序中定义的类相对应的类型),以便 mypy 能够解析整个源代码,而不是仅解析当前行。