我经常遇到函数只接受有限的值集的情况。我知道如何使用typing.Literal
在类型注释中反映此行为,如下所示:
import typing
def func(a: typing.Literal['foo', 'bar']):
pass
我希望有一个decorator @validate_literals
,用于验证的参数是否与其类型一致:
@validate_literals
def picky_typed_function(
binary: typing.Literal[0, 1],
char: typing.Literal['a', 'b']
) -> None:
pass
因此,根据参数类型定义的限制验证输入,并在发生冲突时引发ValueError
:
picky_typed_function(0, 'a') # should pass
picky_typed_function(2, 'a') # should raise "ValueError: binary must be one of (0, 1)')"
picky_typed_function(0, 'c') # should raise "ValueError: char must be one of ('a', 'b')"
picky_typed_function(0, char='c') # should raise "ValueError: char must be one of ('a', 'b')"
picky_typed_function(binary=2, char='c') # should raise "ValueError: binary must be one of (0, 1)"
typing
类型检查被设计为静态的,不会在运行时发生。如何利用类型定义进行运行时验证
我们可以使用^{} 检查修饰(验证)函数的签名,通过^{} (或者,对于python版本<;3.8,使用^{} )获取参数注释的“原点”,检查函数的哪些参数是作为文本别名键入的,并使用[
typing.get_args()
](https://stackoverflow.com/a/64522240/3566606)检索有效值(并在嵌套的文字定义上递归迭代)从文字别名为了做到这一点,剩下要做的就是找出哪些参数已作为位置参数传递,并将相应的值映射到参数的名称,以便可以将该值与参数的有效值进行比较
最后,我们使用带有^{} 的标准配方构建装饰器
这给出了问题中指定的结果
我还发布了python包的alpha版本
runtime-typing
来执行运行时类型检查:https://pypi.org/project/runtime-typing/(文档:https://runtime-typing.readthedocs.io),它处理的情况比typing.Literal
多,例如typing.TypeVar
和typing.Union
瓦尔德克:https://github.com/EvgeniyBurdin/valdec
相关问题 更多 >
编程相关推荐