python3.5的一个新功能是类型提示。例如,下面的代码现在有效:
def greeting(name: str) -> str:
return 'Hello ' + name
但是,据我所知,它本身并没有检查任何东西,而且解释方式与此完全相同:
def greeting(name):
return 'Hello ' + name
主要用于帮助静态分析器(并使代码更容易理解)。但是当将无效类型的参数传递给具有带注释的参数类型的函数时,是否存在(或计划在未来实施)以任何方式(可能通过使用某些第三方库)来发出python throw错误(仅使用类型提示语法)?
答案 0 :(得分:5)
类型提示实现PEP 0484明确列为非目标:
虽然建议的输入模块将包含一些构建块 运行时类型检查 - 特别是get_type_hints()函数 - 必须开发第三方软件包以实现特定的运行时类型检查功能,例如使用 装饰者或元类。使用类型提示来提高性能 优化是留给读者的练习。
由此可见,Python开发人员没有计划添加您所寻求的功能。引用提到装饰者,这似乎是要走的路。在概念中它似乎很简单 - 装饰器将对要装饰的函数使用get_type_hints()
并迭代参数,根据任何提示检查它们的类型,如果存在冲突则抛出错误或者仅仅传递函数的参数。这与pzelasko的答案类似,但装饰者使用提示自动处理锅炉板代码。最简单的方法是简单地审查参数,但是如果返回类型与提示冲突,你也应该能够创建一个会引发错误的装饰器。我还没有Python 3.5并且没有时间去追求它 - 但对于想要了解装饰器和类型提示的人来说,这似乎是一个很好的学习练习。也许你可以成为PEP所暗示的“第三方”之一。
答案 1 :(得分:0)
我认为最简单的方法是检查类型:
def greeting(name):
if type(name) is not str:
raise TypeError('Expected str; got %s' % type(name).__name__)
return 'Hello ' + name
答案 2 :(得分:0)
一个人可以使用库https://github.com/h2oai/typesentry在运行时执行此操作。
答案 3 :(得分: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
在上面的示例中,注册了将引发 NotImplementedError
的基本实现。这是在没有其他实现适合时返回的“回退”实现。
按照基本实现的定义,可以注册任意数量的特定于类型的实现,如示例所示——函数的行为完全不同,具体取决于提供给它的参数的类型,而 { {1}} 方法使用类型注释来注册具有特定 @singledispatch
的函数的特定实现。
一个 type
函数可以有任意数量的参数,但只有第一个参数的类型注释与调用哪个实现相关。