【问题标题】:How to use typehinting for a generic type when you need to create instances of that type in Python当您需要在 Python 中创建该类型的实例时,如何对泛型类型使用类型提示
【发布时间】:2022-10-24 01:25:14
【问题描述】:
我正在创建一个获取字典并创建给定类的实例的类。当前版本有效,但您需要两次告诉该类应将字典转换为哪种类型。
我可以摆脱泛型,但我想继续使用类型提示。
T = TypeVar("T")
class DictsToObjectsParser(Generic[T]):
def __init__(self, object_type: Type[T]):
self.object_type = object_type
def try_to_parse_dicts_to_objects(self, list_dict: List[Dict]) -> List[T]:
object_list: List[T] = []
for my_dict in list_dict:
parsed_object: T = self.object_type(**my_dict)
object_list.append(parsed_object)
return object_list
@staticmethod
def create_instance():
return DictsToObjectsParser[MyClass](MyClass)
我真的需要两次告诉这个班级我想要什么类型吗?
如果没有办法,有没有办法检查 T 和 self.object_type 是否相同(最好在构造函数中)?
【问题讨论】:
标签:
python
python-3.x
generics
type-hinting
【解决方案1】:
告诉它两次是有意义的,类型检查器和解释器都需要知道。解释器可能会在运行时访问类型注释,但我不会这样做。
此外,您的方法有很多问题,如果您解决所有问题,您将到达cattrs。所以我建议立即使用cattrs,cattrs 很棒,可以做所有事情。
【解决方案2】:
不,没有必要:
from typing import Generic, TypeVar
T = TypeVar("T")
class DictsToObjectsParser(Generic[T]):
def __init__(self, object_type: type[T]) -> None:
self.object_type = object_type
reveal_type(DictsToObjectsParser(int))
reveal_type(DictsToObjectsParser(str))
在这段代码上运行 mypy 会得到以下结果:
[...].py:9: note: Revealed type is "[...].DictsToObjectsParser[builtins.int]"
[...].py:10: note: Revealed type is "[...].DictsToObjectsParser[builtins.str]"
如果您绝对想要create_instance 方法,只需将其设为@classmethod 而不是@staticmethod。这说得通;毕竟,您正在使用那个特定的班级在里面:
from __future__ import annotations
from typing import Generic, TypeVar
T = TypeVar("T")
class DictsToObjectsParser(Generic[T]):
def __init__(self, object_type: type[T]) -> None:
self.object_type = object_type
@classmethod
def create_instance(cls, object_type: type[T]) -> DictsToObjectsParser[T]:
return cls(object_type)
reveal_type(DictsToObjectsParser.create_instance(float))
我们再次使用mypy 得到以下信息:
[...].py:14: note: Revealed type is "[...].DictsToObjectsParser[builtins.float]"