Home > Software design >  Make a method return an object of a subclass
Make a method return an object of a subclass

Time:01-12

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 be False
  • (relatedly) the # type: ignore annotation 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__

CodePudding user response:

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
  •  Tags:  
  • Related