'How to get generic types of subclass in Python
I have a generic parent class and a child class that implements the parent with a specific type:
T = TypeVar("T")
class Parent(ABC, Generic[T]):
def get_impl_t(self):
pass
class Child(Parent[int]):
pass
I'd like to get the type of the child class from the parent (see get_impl_t()).
I'm pretty sure this isn't possible without some hackery (inspect.getsource()?) because of type erasure. It's wouldn't work if this didn't have a class hierarchy.
The obvious workaround is add an abstract classmethod that gets the type or add a parameter to the parent class's constructor:
class Parent(ABC, Generic[T]):
def__init__(self, param_cls: Type[T]) -> None:
self.param_cls = param_cls
# or
@classmethod
@abstractmethod
def get_param_cls() -> Type[T]:
pass
This would add some maintenance overhead, so I want to make sure I'm not missing anything.
Solution 1:[1]
You could use typing.get_origin and typing.get_args. So, something to the effect of:
def get_impl_t(self):
for type_ in type(self).__orig_bases__:
if typing.get_origin(type_) is Parent:
return typing.get_args(type_)[0]
How exactly you want to handle things is going to depend on the particulars of your use-case. But here's a demo:
In [1]: import typing
In [2]: from typing import TypeVar, Generic
In [3]: T = TypeVar("T")
...:
...: class Parent(Generic[T]):
...: def get_impl_t(self):
...: for type_ in type(self).__orig_bases__:
...: if typing.get_origin(type_) is Parent:
...: return typing.get_args(type_)[0]
...:
...: class Child(Parent[int]):
...: pass
...:
In [4]: Child().get_impl_t()
Out[4]: int
And with another child:
In [5]: class AnotherChild(Parent[str]):
...: pass
...:
In [6]: AnotherChild().get_impl_t()
Out[6]: str
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | juanpa.arrivillaga |
