如何将 Python 字符串类型注释转换为正确的类型?
How to convert Python string type annotation to proper type?
一些 Python 类型注释可以指定为字符串,例如允许递归。但是,我需要获得正确的类型以进行运行时评估。如果我 from __future__ import annotations
也使用字符串,这将成为 Python 3.10 中的默认设置(如果我没看错的话)。鉴于这些字符串,我需要获得正确的类型。
例如,在这段代码中,如果我不从 future 导入,字段类型是 <class 'int'>
,如果我从 future 导入,则字段类型是 "ObjectId"
。更重要的是,仅当我不进行导入时,... is int
的检查才为真。
# Toggle the comment on the next line
# from __future__ import annotations
import dataclasses
ObjectId = int
@dataclasses.dataclass
class Sample:
id: ObjectId
def main() -> None:
fields = dataclasses.fields(Sample)
print(fields[0].type)
print(fields[0].type is int)
main()
如何将基于字符串的类型注释转换为正确的 class 类型?
from __future__ import annotations
import dataclasses
from typing import get_type_hints
ObjectId = int
@dataclasses.dataclass
class Sample:
id: ObjectId
def main() -> None:
hints = get_type_hints(Sample)
print(hints['id'])
print(hints['id'] is int)
if __name__ == "__main__":
main()
<class 'int'>
True
注意:我发现这种方法可能会很慢,所以为了节省内存,我缓存了结果:
from functools import cache
from typing import Any, Type, get_type_hints
@cache
def get_cached_type_hints(clazz: Type[Any]) -> dict[str, Type[Any]]:
return get_type_hints(clazz)
一些 Python 类型注释可以指定为字符串,例如允许递归。但是,我需要获得正确的类型以进行运行时评估。如果我 from __future__ import annotations
也使用字符串,这将成为 Python 3.10 中的默认设置(如果我没看错的话)。鉴于这些字符串,我需要获得正确的类型。
例如,在这段代码中,如果我不从 future 导入,字段类型是 <class 'int'>
,如果我从 future 导入,则字段类型是 "ObjectId"
。更重要的是,仅当我不进行导入时,... is int
的检查才为真。
# Toggle the comment on the next line
# from __future__ import annotations
import dataclasses
ObjectId = int
@dataclasses.dataclass
class Sample:
id: ObjectId
def main() -> None:
fields = dataclasses.fields(Sample)
print(fields[0].type)
print(fields[0].type is int)
main()
如何将基于字符串的类型注释转换为正确的 class 类型?
from __future__ import annotations
import dataclasses
from typing import get_type_hints
ObjectId = int
@dataclasses.dataclass
class Sample:
id: ObjectId
def main() -> None:
hints = get_type_hints(Sample)
print(hints['id'])
print(hints['id'] is int)
if __name__ == "__main__":
main()
<class 'int'>
True
注意:我发现这种方法可能会很慢,所以为了节省内存,我缓存了结果:
from functools import cache
from typing import Any, Type, get_type_hints
@cache
def get_cached_type_hints(clazz: Type[Any]) -> dict[str, Type[Any]]:
return get_type_hints(clazz)