s-m*_*m-e 20 python type-hinting dynamic-typing python-typing
我在几个项目中使用Typeguard在 Python 运行时进行类型检查。它运作得很好。
我遇到过一种情况,函数参数的类型是typing.Union由一些动态收集的数据类型组成的。例如
def find_datatypes():
# some stuff ...
return (str, int) # dynamically generated list / tuple
datatypes = find_datatypes()
Run Code Online (Sandbox Code Playgroud)
现在我想生成一个typing.Unionfromdatatypes以便最终在函数中使用。我期望解包语法能够工作:
my_union = typing.Union[*datatypes]
@typeguard.typechecked
def some_function(param: my_union):
pass
Run Code Online (Sandbox Code Playgroud)
然而,它并没有:
my_union = typing.Union[*datatypes]
^
SyntaxError: invalid syntax
Run Code Online (Sandbox Code Playgroud)
我怎样才能实现我想要的目标?
use*_*ica 17
你可以这样做:
my_union = typing.Union[datatypes]
Run Code Online (Sandbox Code Playgroud)
在运行时,thing[x, y]已经相当于thing[(x, y)].
也就是说,有一些限制需要记住。特别是,当使用字符串注释时,my_union必须在some_function的全局命名空间typeguard或其他任何东西中可用,才能在运行时解析注释。这限制了很多闭包用例,以及很多动态添加注释的尝试。(字符串注释最终可能会成为默认值,但开发人员正在考虑其他选项,目前计划尚不清楚。)
另外,正如您所期望的,mypy 不会认为这些都是有效的。
我正在使用 pydantic 自动生成 OpenAPI 规范。
import typing
from pydantic import BaseModel
class Parent(BaseModel):
@classmethod
def get_subclasses(cls):
return tuple(cls.__subclasses__())
class Child1(Parent):
pass
class Child2(Parent):
pass
datatypes = typing.Union[Parent.get_subclasses()]
Run Code Online (Sandbox Code Playgroud)
它之所以有效只是因为get_subclasses返回一个元组。我发布这个答案是因为__subclasses__调用返回一个列表,我挠了挠头,因为我无法理解为什么 @user2357112 解决方案在我的情况下不起作用。事实上,确实如此,但我没有注意到他们使用了元组。
否则,你会遇到
TypeError: Union[arg, ...]: each arg must be a type. Got [<class '__main__.Child1'>, <class '__main__.Child2'>].
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5033 次 |
| 最近记录: |