如何覆盖动态创建的类实例的方法



我无法更改的代码的类具有返回自身实例的方法from_lowercase。现在我想继承一个类。但是,当通过from_lowercase调用继承的类时,会返回原始类的实例。

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

举几个例子:

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())

导致以下情况:

I am JOHN
I am JOHN
Hello dear sir, I am MARIA!
I am MARIA

然而,所需的输出如下:

I am JOHN
I am JOHN
Hello dear sir, I am MARIA!
Hello dear sir, I am MARIA!

显然,nice_animal_from_lowercaseAnimal的实例,而不是PoliteAnimal。如何解决这个问题?

您需要在子类上实现相同的方法,这样它就会被覆盖

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())

输出:

I am JOHN
I am JOHN
Hello dear sir, I am MARIA!
Hello dear sir, I am MARIA!

我会修补Animal来修复from_lowercase,它应该是一个类方法,而不是静态方法。

def from_lowercase(cls, lc: str):
return cls(lc.upper())
Animal.from_lowercase = classmethod(from_lowercase)

即使在定义了PoliteAnimal之后执行此操作,也能正常工作。

当您调用PoliteAnimal.from_lowercase(...)时,方法查找将导致对Animal.from_lowercase的调用,但作为类方法,它将接收PoliteAnimal作为其第一个参数,从而实例化正确的类。

最新更新