How can I implement a custom constructor (class method) that is inheritable in python?
The following minimized example might give an idea:
JavaScript
x
24
24
1
from dataclasses import dataclass
2
from typing import Type, TypeVar
3
4
T = TypeVar("T")
5
6
7
@dataclass
8
class Parent:
9
something: int = 2
10
11
@classmethod
12
def from_float(cls: Type[T], something_as_float: float) -> T:
13
return Type[T](something=int(something_as_float))
14
15
16
@dataclass
17
class Child(Parent):
18
""" Should also be constructible via from_float
19
"""
20
21
22
assert isinstance(Parent.from_float(1.0), Parent)
23
assert isinstance(Child.from_float(1.0), Child)
24
mypy does not like the constructor I call when returning from from_float. I don’t know how to refer to class (Parent or Child) from the class method.
Advertisement
Answer
Pass the bound
argument to TypeVar
to specify that the type is a subclass of Parent
. This lets mypy know that the type has the something
attribute
When you create the instance use cls
not Type[T]
JavaScript
1
23
23
1
from dataclasses import dataclass
2
from typing import Type, TypeVar
3
4
T = TypeVar("T", bound='Parent')
5
6
7
@dataclass
8
class Parent:
9
something: int = 2
10
11
@classmethod
12
def from_float(cls: Type[T], something_as_float: float) -> T:
13
return cls(something=int(something_as_float))
14
15
16
@dataclass
17
class Child(Parent):
18
pass
19
20
21
assert isinstance(Parent.from_float(1.0), Parent)
22
assert isinstance(Child.from_float(1.0), Child)
23