Reputation: 91
A class I cannot change the code of has a method from_lowercase
that returns an instance of itself. Now I would like to inherit a class. However, when calling the inherited class over from_lowercase
an instance of the original class is returned.
class Animal:
"""I CANNOT change the code in this class"""
def __init__(self, uppercase_name: str):
self.uppercase_name = uppercase_name
def say(self) -> str:
return f"I am {self.uppercase_name}"
@staticmethod
def from_lowercase(lowercase_name: str) -> "Animal":
return Animal(lowercase_name.upper())
class PoliteAnimal(Animal):
def say(self) -> str:
return f"Hello dear sir, {super().say()}!"
# insert magic here
calling some examples:
animal = Animal("JOHN")
animal_from_lowercase = Animal.from_lowercase("john")
nice_animal = PoliteAnimal("MARIA")
nice_animal_from_lowercase = PoliteAnimal.from_lowercase("maria")
print(animal.say())
print(animal_from_lowercase.say())
print(nice_animal.say())
print(nice_animal_from_lowercase.say())
leads to the following:
I am JOHN
I am JOHN
Hello dear sir, I am MARIA!
I am MARIA
However, the desired output is the following:
I am JOHN
I am JOHN
Hello dear sir, I am MARIA!
Hello dear sir, I am MARIA!
Obviously nice_animal_from_lowercase
is an instance of Animal
and not PoliteAnimal
. How can this be fixed?
Upvotes: 2
Views: 66
Reputation: 531055
I would patch Animal
to fix from_lowercase
, which should be a class method, not a static method.
def from_lowercase(cls, lc: str):
return cls(lc.upper())
Animal.from_lowercase = classmethod(from_lowercase)
This works even if you do it after PoliteAnimal
is defined.
When you call PoliteAnimal.from_lowercase(...)
, the method lookup will result in a call to Animal.from_lowercase
, but as a class method it will receive PoliteAnimal
as its first argument, leading to the correct class being instantiated.
Upvotes: 2
Reputation: 137
You need to implement the same method on your subclass so it will be overridden
class PoliteAnimal(Animal):
def say(self) -> str:
return f"Hello dear sir, {super().say()}!"
# insert magic here
@staticmethod
def from_lowercase(lowercase_name: str) -> "Animal":
return PoliteAnimal(lowercase_name.upper())
Ouput:
I am JOHN
I am JOHN
Hello dear sir, I am MARIA!
Hello dear sir, I am MARIA!
Upvotes: 2