【问题标题】:python 3.5 type hints: can i check if function arguments match type hints?python 3.5 类型提示:我可以检查函数参数是否匹配类型提示?
【发布时间】:2016-12-10 07:38:19
【问题描述】:

python 3.5 是否提供允许测试给定的函数是否 参数是否符合函数声明中给出的类型提示?

如果我有例如这个函数:

def f(name: List[str]):
    pass

有没有python方法可以检查是否

name = ['a', 'b']
name = [0, 1]
name = []
name = None
...

适合类型提示?

我知道“运行时不会进行类型检查”,但我仍然可以检查 这些参数在 python 中的有效性?

或者如果 python 本身不提供该功能:我想要的工具是什么 需要用吗?

【问题讨论】:

  • “python 3.5 是否提供了允许测试给定参数是否符合函数声明中给出的类型提示的函数?” - 没有(但它是getting closer) . “我需要使用什么工具?” - 建议偏离主题(但请参阅 MyPy、contracts 等)

标签: python python-internals python-3.5


【解决方案1】:

Python 本身不提供此类功能,您可以阅读更多关于它的信息here


我为此写了一个装饰器。这是我的装饰器的代码:

from typing import get_type_hints

def strict_types(function):
    def type_checker(*args, **kwargs):
        hints = get_type_hints(function)

        all_args = kwargs.copy()
        all_args.update(dict(zip(function.__code__.co_varnames, args)))

        for argument, argument_type in ((i, type(j)) for i, j in all_args.items()):
            if argument in hints:
                if not issubclass(argument_type, hints[argument]):
                    raise TypeError('Type of {} is {} and not {}'.format(argument, argument_type, hints[argument]))

        result = function(*args, **kwargs)

        if 'return' in hints:
            if type(result) != hints['return']:
                raise TypeError('Type of result is {} and not {}'.format(type(result), hints['return']))

        return result

    return type_checker

你可以这样使用它:

@strict_types
def repeat_str(mystr: str, times: int):
    return mystr * times

虽然限制你的函数只接受一种类型并不是很pythonic。虽然您可以使用 abc(抽象基类),如 number(或自定义 abc)作为类型提示,并限制您的函数不仅接受一种类型,而且接受您想要的任何类型组合。


为它添加了一个 github repo,如果有人想使用它。

【讨论】:

  • 这看起来不错。 f.__code__ 应该是 function.__code__;第一个TypeError 的参数也应该被调整。我尝试了您的 repeat_str 函数并收到一条(意外)错误消息:TypeError: Type of mystr is <class 'str'> and not <class 'str'>。但也许我在你的代码中引入了一个错误......
  • @hiroprotagonist,对不起,我给你错了,不是调试代码。我编辑了我的答案,现在它可能可以正常工作了。
  • 嗨,这实际上是一个非常好的答案。但也许hints = get_type_hints(function) 可以放在装饰器函数之外:每次执行函数时都不需要计算它们:)
【解决方案2】:

这是一个老问题,但我编写了一个工具来根据类型提示进行运行时类型检查:https://pypi.org/project/typeguard/

【讨论】:

  • typeguard 看起来很不错。处理 ListUnionTypevar 等,这是概念验证接受的答案不会做的事情。看看运行它会对性能造成什么影响会很有趣,尽管我想这可以通过例如仅在调试中运行。
猜你喜欢
  • 2017-12-03
  • 1970-01-01
  • 2016-12-06
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
  • 1970-01-01
  • 2015-10-17
  • 2020-11-30
相关资源
最近更新 更多