Home > Back-end >  In python, is there a way to specify the return type of parent(base) function without overriding it?
In python, is there a way to specify the return type of parent(base) function without overriding it?

Time:01-03

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 :

  1. get() will do the exact same for all child classes, except the return result will have a different type.
  2. 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.

  • Related