I want to provide method to a class, so that it gets transformed into a special case, represented by a subclass. I’m not sure, however what is the best way to do it.
Here is an illustrative example:
class Vector(pd.Series):
def normalize(self) -> "NormalizedVector":
result: "NormalizedVector" = self / sum(self) # type:ignore
return result
class NormalizedVector(Vector):
pass
There are issues with this implementation, though:
isinstance(vector.normalize(), NormalizedVector)will beFalse- (relatedly) the
# type: ignoreannotation is required for static type checking
So my question is: what is a clean way of achieving this?
The alternative I found was using dynamic allocation:
class Vector(pd.Series):
pass
class NormalizedVector(Vector):
pass
def normalize_vector(self: Vector) -> NormalizedVector:
return NormalizedVector(self / sum(self))
Vector.normalize = normalize_vector
However:
- I find it makes the code much less readable
- I’m afraid to be messing with the end method metadata, such as
__name__
>Solution :
A type hint alone doesn’t cause a value to become the hinted type. You need to create an instance. Your second approach works because you actually created that instance. The explicit assignment is unnecessary.
class Vector(pd.Series):
def normalize(self) -> "NormalizedVector":
return NormalizedVector(self / sum(self))
class NormalizedVector(Vector):
pass