So for example, I know I can achieve my goal by doing this :
class Base :
def get(self) -> Any:
return ...
class Child(Base) :
def get(self) -> FooClass:
return super().get()
My goal here is to do the followings :
- get() will do the exact same for all child classes, except the return result will have a different type.
- I just want the IDE to know that my child will return a different type, without having to kinda redefine the entire list of functions. so basically, I'd want something like this to work (which doesn't at the moment)
class Base :
T = TypeVar('T')
return_type: T
def get(self) -> return_type:
return 0
class Child(Base) :
return_type = FooClass
And I want my IDE to recognize that Child().get() will return a FooClass Type (which is currently not, using VSCode and not sure if this already works in other IDEs).
Is there a way to achieve this? (I currently am aware of the usage of https://peps.python.org/pep-0484/#annotating-instance-and-class-methods ), but this is basically about changing its return type to the class itself, not really explicitly changing the type of return type myself.)
CodePudding user response:
Do you mean a generic like so?
import typing
_T = typing.TypeVar('_T')
class Base(typing.Generic[_T]):
def get(self) -> _T:
return ... # type: ignore
class ChildInt(Base[int]):
pass
class ChildStr(Base[str]):
pass
ChildInt().get() # int
ChildStr().get() # str
A Generic
is subscriptable and allows you to define a class that can act on different types.
If you're not planning to actually change the subclasses, just use the Base
class with the generic:
inst: Base[int] = Base()
inst.get() # int
For more info please see the relevant documentation. Do note that the case I presented is an invariant generic. You can also have covariant and contravariants per _T
definition. These are out of scope but I can explain should questions arise.