我试图编写一个函数装饰器,它使用Python 3.6类型提示来检查参数字典是否尊重类型提示,如果没有清晰描述问题,则会产生错误,用于HTTP API。
问题是,当函数有一个使用Union
类型的参数时,我无法在运行时对照它检查变量。
比如我有这个功能
from typing import Union
def bark(myname: str, descr: Union[int, str], mynum: int = 3) -> str:
return descr + myname * mynum
我可以做到:
isinstance('Arnold', bark.__annotations__['myname'])
但不是:
isinstance(3, bark.__annotations__['descr'])
因为Union
不能与is实例
或issubclass
一起使用。
我找不到使用type对象检查它的方法。我试图自己实现检查,但当吠叫时。__annotations__['desr']
显示为键入。在REPL中的Union[int, str]
我不能在运行时访问类型列表,如果不使用检查bark的丑陋黑客。__annotations__['desr']。__repr__()
。
是否有适当的方式访问此信息?还是故意让它在运行时不易访问?
MSeifert接受的现有答案(https://stackoverflow.com/a/45959000/7433423)不会将Union
s与其他泛型类型区分开来,并且由于参数化Union
类型上的isinstance()
和issubclass()
的行为,在运行时很难确定类型批注是Union
还是其他泛型类型,如Mapping
。
似乎泛型类型将具有一个未记录的__origin__
属性,该属性将包含对用于创建它的原始泛型类型的引用。一旦您确认类型注释是参数化的Union
,您就可以使用也未记录的__args__
属性来获取类型参数。
>>> from typing import Union
>>> type_anno = Union[int, str]
>>> type_anno.__origin__ is Union
True
>>> isinstance(3, type_anno.__args__)
True
>>> isinstance('a', type_anno.__args__)
True
您可以使用Union
的__args__
属性,其中包含可能内容的元组
:
>>> from typing import Union
>>> x = Union[int, str]
>>> x.__args__
(int, str)
>>> isinstance(3, x.__args__)
True
>>> isinstance('a', x.__args__)
True
\uuuu args\uuuu
参数没有文档化,因此可以认为它“弄乱了实现细节”,但它似乎比解析repr
更好。
在Python3.8及更高版本中,MSeifert和Richard Xia建议的方法可以通过不使用未记录的属性\uuuuuu origin\uuuu
和\uuu args\uuu
来改进。此功能由新函数键入提供。获取参数(tp)
和键入。获取原点(tp)
:
>> from typing import Union, get_origin, get_args
>> x = Union[int, str]
>> get_origin(x), get_args(x)
(typing.Union, (<class 'int'>, <class 'str'>))
>> get_origin(x) is Union
True
>> isinstance(3, get_args(x))
True
>> isinstance('a', get_args(x))
True
>> isinstance([], get_args(x))
False
附言:我知道这个问题是关于Python 3.6的(可能是因为这是当时最新的版本),但是当我作为Python 3.8用户搜索解决方案时,我来到了这里。我想其他人可能也有同样的情况,所以我认为在这里增加一个新的答案是有意义的。
问题内容: 更新(2020年9月) :Python 3.9包含此用例的功能,请参阅https://docs.python.org/3.9/library/typing.html#typing.get_type_hints 我正在尝试编写一个使用Python 3.6类型提示的函数装饰器,以检查参数字典是否尊重类型提示,并且如果未出现带有问题清晰说明的错误,则将其用于HTTP API。 问题是,当函数
问题内容: 我几乎没有这样声明的C函数 我想将这些作为一个Go函数公开 所以我需要能够在运行时检查 参数 类型。我该怎么做,这是个好主意吗(如果不是,在这种情况下,什么是好的做法)? 问题答案: 在此处查看类型断言: http://golang.org/ref/spec#Type_assertions 我只断言一个明智的类型(字符串,uint64)等,并使其尽可能宽松,最后执行到本机类型的转换。
我试图找到一种方法来传递一个对象来发挥作用,并在运行库中检查它的类型。这是一个伪代码: 但是总是返回,我无法找到获取或的真正类型的方法。也不起作用,返回了相同的内容。
我在android和Kotlin有奇怪的问题。问题是我用类型定义变量,但在运行时更改为 我这样定义我的变量: 我使用kotlin 1.3.71和jvm 1.8。 更新0:
是否有可能创建一个typeGuard,或者其他实现相同目的的东西,来检查一个变量是否是打字稿联合中的特定接口类型?
问题内容: 假设通用类型声明(Java) 我如何在运行时实例化一个Type对象,该对象表示通过特定类型T(也仅在运行时才知道)进行参数化的Foo? 问题答案: 我想我明白你的问题。您想要序列化一个,并且在运行时具有class对象(但在编译时不是固定的)。因此,在Gson中建议的创建匿名子类的解决方案不起作用,因为这要求在编译时对参数化类型(例如)进行硬编码,并且如果使用,则该解决方案不起作用。 但