[英]How to make only a method generic in a python class
I have the following base class to represent fields:我有以下基数 class 来表示字段:
T = TypeVar("T")
@dataclass
class BaseClass(Generic[T]):
def validate(self, value: T):
raise NotImplementedError
I also have an enum to represent the available implementations of this class:我还有一个枚举来表示这个 class 的可用实现:
class Types(Enum):
A = auto()
B = auto()
@staticmethod
def from_instance(instance: BaseClass) -> "Types":
if isinstance(instance, ClassA):
return Types.A
if isinstance(instance, ClassB):
return Types.B
raise ValueError("Not supported")
Now, from these class, I have several implementations:现在,从这些 class,我有几个实现:
@dataclass
class ClassA(BaseClass[str]):
def validate(self, value: str):
pass
@dataclass
class ClassB(BaseClass[int]):
def validate(self, value: int):
pass
After this setup, I have another class to store a list of BaseClass
:完成此设置后,我有另一个 class 来存储BaseClass
列表:
@dataclass
class Container:
instances: List[BaseClass]
def get_by_type(self, type: Types) -> List[BaseClass]:
return [instance for instance in self.instances if type == Types.from_instance(instance)]
At the end I have the following code and the following error:最后我有以下代码和以下错误:
def function(fields_from_class_a: List[ClassA]):
print(fields_from_class_a)
container = Container(instances=[ClassA(), ClassB()])
fields = container.get_by_type(Types.A)
# throws error:
# Argument 1 to "function" has incompatible type "List[BaseClass[Any]]"; expected "List[ClassA]"
function(fields)
So my question is, can I modify the code in such a way that the method get_by_type
is correctly typed?所以我的问题是,我可以修改代码以正确输入方法get_by_type
吗?
ClassA
is only mapped at runtime to Types.A
in Types.from_instance()
. ClassA
仅在运行时映射到Types.A
Types.from_instance()
中的 Types.A。
You would have to use BaseClass[Literal[Types.A]]
instead of ClassA
:您将不得不使用BaseClass[Literal[Types.A]]
而不是ClassA
:
# def function(fields_from_class_a: List[ClassA]): # Change this
def function(fields_from_class_a: List[BaseClass[Literal[Types.A]]]): # to this
And type Container.get_by_type()
as such:并输入Container.get_by_type()
这样的:
TypesT = TypeVar("TypesT", Literal[Types.A], Literal[Types.B]) # Add this
# def get_by_type(self, type: Types) -> List[BaseClass]: # Change this
def get_by_type(self, type: TypesT) -> List[BaseClass[TypesT]]: # to this
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.