Home > Mobile >  Hinting specific types for attributes in subclasses where parent can have many types
Hinting specific types for attributes in subclasses where parent can have many types

Time:05-06

I have a parent class Foo which has an attribute bar. It has two subclasses which each have bar as a different type: FooStr has bar as a str, and FooInt has bar as an int. Foo is an abstract base class.

How can I hint the specific type of an attribute in subclasses where the parent can have many types?

This is what I started with. The hinting for the subclasses FooStr and FooInt tells me bar is a union of str or int, not very useful.

class Foo(abc.ABC):
    def __init__(self, bar: typing.Union[str, int], stuff):
        self.bar = bar
        self.stuff = stuff

class FooStr(Foo):
    pass

class FooInt(Foo):
    pass

Next I tried hinting the types in the init methods of the subclasses, but the hinting for bar in the subclasses still shows the type as a union.

class Foo(abc.ABC):
    def __init__(self, bar: typing.Union[str, int], stuff):
        self.bar = bar
        self.stuff = stuff

class FooStr(Foo):
    def __init__(self, bar: str, stuff):
        super().__init__(self, bar, stuff)

class FooInt(Foo):
    def __init__(self, bar: int, stuff):
        super().__init__(self, bar, stuff)

Then I tried removing bar from the parent init which hints the correct types for the subclasses, but not defining bar in the parent class Foo seems incorrect to me.

class Foo(abc.ABC):
    def __init__(self, stuff):
        self.stuff = stuff

class FooStr(Foo):
    def __init__(self, bar: str, stuff):
        self.bar = bar
        super().__init__(self, stuff)

class FooInt(Foo):
    def __init__(self, bar: int, stuff):
        self.bar = bar
        super().__init__(self, stuff)

Not sure where to go from here...

CodePudding user response:

Use the Generic base class, you can then pass the variable type when subclassing your parent class

from typing import Generic, TypeVar


T = TypeVar('T')


class Foo(Generic[T]):
    def __init__(self, bar: T, stuff):
        self.bar = bar
        self.stuff = stuff


class FooStr(Foo[str]):
    pass


class FooInt(Foo[int]):
    pass
  • Related