fre*_*bie 7 python annotations type-hinting inspect python-3.x
我试图通过使用模块中的signature()
函数,基于我在一些Python函数中提供的类型注释生成一些JavaScript inspect
.
当类型是一个简单的内置类时,这部分可以正常工作:
import inspect
def my_function() -> dict:
pass
signature = inspect.signature(my_function)
signature.return_annotation is dict # True
Run Code Online (Sandbox Code Playgroud)
虽然我不知道如何打开和检查更复杂的注释,例如:
from typing import List
import inspect
def my_function() -> List[int]:
pass
signature = inspect.signature(my_function)
signature.return_annotation is List[int] # False
Run Code Online (Sandbox Code Playgroud)
再次引用自定义类的类似问题:
def my_function() -> List['User']:
pass
...
signature.return_annotation # typing.List[_ForwardRef('User')]
Run Code Online (Sandbox Code Playgroud)
我想要的是这样的 - 所以我可以在生成JavaScript时适当地分支:
type = signature.return_annotation... # list
member_type = signature.return_annotation... # int / 'User'
Run Code Online (Sandbox Code Playgroud)
谢谢.
List
不是类型映射到GenericMeta
,尽管有语法。每次访问它都会生成一个新实例:
>>> [ id(List[str]) for i in range(3) ]
[33105112, 33106872, 33046936]
Run Code Online (Sandbox Code Playgroud)
这意味着即使List[int] is not List[int]
. 要比较两个实例,您有多种选择:
==
,即signature.return_annotation == List[int]
。将您的类型的实例存储在全局变量中并进行检查,即,
a = List[int]
def foo() -> a:
pass
inspect.signature(foo).return_annotation is a
Run Code Online (Sandbox Code Playgroud)使用issubclass
. 打字模块定义了这一点。请注意,这可能比您想要的更多,_TypeAlias
如果您使用它,请务必阅读文档。
List
仅核对并自己阅读内容。尽管该属性是内部的,但实现不太可能很快改变:List[int].__args__[0]
包含从 Python 3.5.2 开始的类型参数,在早期版本中,它的List[int].__parameters__[0]
.如果您想为导出器编写通用代码,那么最后一个选项可能是最好的。如果您只需要涵盖特定用例,我个人会使用==
.
小智 5
Python的3.8提供了typing.get_origin()
与typing.get_args()
此!
assert get_origin(Dict[str, int]) is dict
assert get_args(Dict[int, str]) == (int, str)
assert get_origin(Union[int, str]) is Union
assert get_args(Union[int, str]) == (int, str)
Run Code Online (Sandbox Code Playgroud)
请参阅https://docs.python.org/3/library/typing.html#typing.get_origin