21

python3.5 的新特性之一是类型提示。例如下面的代码现在有效:

def greeting(name: str) -> str:
    return 'Hello ' + name

但是,据我了解,它不会自行检查任何内容,并且其解释方式也与此完全相同:

def greeting(name):
    return 'Hello ' + name

并且主要是为了帮助静态分析器(并使代码更易于理解)而实现的。但是,当一个无效类型的参数被传递给一个带注释的参数类型的函数时(仅使用类型提示语法)?

4

5 回答 5

16

类型提示实现PEP 0484,它明确列为非目标

虽然提议的类型模块将包含一些用于运行时类型检查的构建块——特别是 get_type_hints() 函数——但必须开发第三方包来实现特定的运行时类型检查功能,例如使用装饰器或元类。使用类型提示进行性能优化留给读者作为练习。

由此看来,Python 开发人员没有计划添加您所寻求的功能。引用提到了装饰器,这似乎是要走的路。在概念上看起来很简单——装饰器会使用get_type_hints()在要装饰的函数上,并遍历参数,根据任何提示检查它们的类型,如果发生冲突则抛出错误,或者只是将参数传递给函数。这将类似于 pzelasko 的答案,但装饰器使用提示自动处理样板代码。最简单的方法是简单地检查参数,尽管您还应该能够制作一个装饰器,如果返回类型与提示冲突,它将引发错误。我还没有 Python 3.5,也没有时间去研究它——但对于想要了解装饰器和类型提示的人来说,这似乎是一个很好的学习练习。也许您可以成为 PEP 所暗示的“第三方”之一。

于 2015-09-19T12:11:33.963 回答
1

我认为最简单的方法是检查类型:

def greeting(name):
    if not isinstance(name, str):
        raise TypeError('Expected str; got %s' % type(name).__name__)
    return 'Hello ' + name
于 2015-09-19T11:17:19.190 回答
0

可以使用库https://github.com/h2oai/typesentry在运行时执行此操作。

于 2020-10-29T12:30:24.057 回答
0

自 python 3.7 发布以来,可以使用functools.singledispatch.

from functools import singledispatch

@singledispatch
def greet(arg: object):
    raise NotImplementedError(f"Don't know how to greet {type(arg)}")

@greet.register
def _(arg: str):
     print(f"Hello, {arg}!")
    
@greet.register
def _(arg: int):
    print(', '.join("Hello" for _ in range(arg)), "!")

greet("Bob")          # string implementation is called — prints "Hello, Bob!"
greet(4)              # int implementation is called — prints "Hello, Hello, Hello, Hello!"
greet(["Alice, Bob"]) # no list implementation, so falls back to the base implementation — will raise an exception

在上面的示例中,注册了一个将 raise 的基本实现NotImplementedError。如果其他实现都不适合,这是返回的“后备”实现。

在基本实现的定义之后,可以注册任意数量的特定于类型的实现,如示例所示 - 函数的行为完全不同,具体取决于提供给它的参数的类型,并且该@singledispatch方法使用类型注释用某个 .注册某个函数的某个实现type

一个singledispatch函数可以有任意数量的参数,但只有第一个参数的类型注释与调用哪个实现相关。

于 2021-07-26T01:16:16.480 回答
0

如果使用 Python3.6 注解,可以使用 typeguard 装饰器: https ://typeguard.readthedocs.io/en/latest/userguide.html#using-the-decorator

注意:这应该只是一个“调试”或“测试”工具,而不是生产工具。因此,他们建议将 -O 选项添加到 python 以在没有生产的情况下运行。

它不会自动检查内联变量注释检查,仅检查函数参数、函数返回和对象类型。

从文档:

from typeguard import typechecked

@typechecked
def some_function(a: int, b: float, c: str, *args: str) -> bool:
    ...
    return retval

@typechecked
class SomeClass:
    # All type annotated methods (including static and class methods and properties)
    # are type checked.
    # Does not apply to inner classes!
    def method(x: int) -> int:
        ...

您还可以通过以下方式自动执行所有功能:

with install_import_hook('myapp'):
    from myapp import some_module
于 2021-10-01T09:21:19.163 回答