【问题标题】:How to perform type checking with the typing Python module?如何使用打字 Python 模块执行类型检查?
【发布时间】:2016-06-22 16:37:53
【问题描述】:

我正在阅读 typing 模块代码并查看 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

我想过从它的值重新创建对象类型,例如:

>>> get_type([1])
typing.List<~T>[int]

但这不适用于issubclass

>>> issubclass(typing.List[int], typing.List[typing.Any])
False

我没有看到一种简单的方法来检查 Python 中的类型而不假设很多关于 the internals of the typing stdlib module 的事情(例如,访问 __args____tuple_params__)。

如何正确实现适用于前面列出的案例的check_type 函数?我正在使用 Python 2.7。

【问题讨论】:

  • 这不就是isinstance吗?
  • 不,@user2357112。 isinstance 不完全检查类型。例如:isinstance(['string'], typing.List[int]) is True 当这不是我想要的。
  • @freakish:查看mypy,这是一个用于 Python 的静态类型分析工具,也是类型提示背后的主要驱动力之一。
  • 不是一个真正的答案,但检查类型的pythonic方法是使用try/except语句并将您要测试的值视为您期望的值,如果引发TypeError异常,请执行别的东西或只是通过
  • @freakish:PEP-484(已接受)。虽然它并不完全适用于 Python 2.7。

标签: python typing


【解决方案1】:

对于问题中提供的简单示例,您可以轻松获得非常有限的功能:

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]')

您甚至可以通过稍微扩展此代码来做一些更高级的事情(例如,引用与您在程序中定义的类对应的类型),以便 mypy 解析您的整个源代码,而不仅仅是当前行。

或者,您可能想查看enforcetypeguard

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-07-06
    • 2021-04-09
    • 2022-01-23
    • 2015-10-27
    • 1970-01-01
    • 1970-01-01
    • 2018-11-03
    相关资源
    最近更新 更多