如何覆盖 SUBclass 中依次覆盖 SUPERclass 的函数(Python)?
Posted
技术标签:
【中文标题】如何覆盖 SUBclass 中依次覆盖 SUPERclass 的函数(Python)?【英文标题】:How can I override the function in SUBclass that overrides the SUPERclass in turn (Python)? 【发布时间】:2021-12-12 14:43:51 【问题描述】:我需要重写之前已经重写了 SuperClass 的 SubClass1。它看起来像这样:
class SuperClass:
def function(self, args: List[str] = None):
# some code
class SubClass1(SuperClass):
@overrides(SuperClass)
def function(self, args: List[str] = None):
# some code
super().function(args)
class SubClass2(SubClass2):
@classmethod
@overrides(SubClass2)
def function(self, args: List[str] = None):
# some code
super().function(args)
SuperClass1 和 SuperClass2 中的函数只有一个区别。这是没有一个命令。我没有更改任何参数。
我不确定是否可以通过这种方式覆盖函数。但是,我只在最后一步遇到问题,我在 SubClass2
中调用 super()
> super().function(args)
E TypeError: super(type, obj): obj must be an instance or subtype of type
可能,我最初犯了一个愚蠢的错误,因为在我的情况下,我必须在 SubClass2
中使用 @classmethod
,而我的 IDE 告诉我在此函数中使用 cls
而不是 self
。
overrides
函数:
def overrides(interface_class):
"""Marks method as override of parent class' method"""
def overrider(method):
assert (method.__name__ in dir(interface_class))
return method
return overrider
【问题讨论】:
overrides
装饰器从何而来?此外,您的缩进似乎错误 - 请提供minimal reproducible example。解释一下为什么要尝试用 class 方法覆盖 instance 方法会很有帮助。
也许overrides
是pytests
的一部分,所以我不使用导入。我对 overrides
装饰器的理解是否正确?我不确定我的缩进是否完全错误,因为它有效。 minimal reproducible example
怎么样?我不确定我是否可以在这里提供更多信息的示例,因为这段代码有很多依赖关系并且它的逻辑非常棘手。不过,我希望我已经展示了主要方案是如何工作的。
我怀疑是我的错误:you're trying to override an instance method with a class method.
如你所说。
嗯,它肯定不是像classmethod
那样的built-in function,而且我在the pytest API 中也看不到它。如果你不能给人们一些让他们重现问题的东西,他们可能无法帮助你解决它。
我找到了overrides
函数,是的,我导入了这个)
【参考方案1】:
您收到错误是因为在SubClass2
中您使用的是@classmethod
装饰器,因此您必须在调用super()
方法之前初始化一个类实例。您还必须向类实例传递一个参数,因为在类方法上下文中没有 self
:
from typing import List
class SuperClass:
def __init__(self, name="Name"):
self.name = name
def function(self, args: List[str] = None):
print("SuperClass")
print(self.name)
class SubClass1(SuperClass):
def function(self, args: List[str] = None):
print("SubClass1")
super().function(args)
class SubClass2(SubClass1):
@classmethod
def function(cls, args: List[str] = None):
new_class = cls("New Name")
print("SubClass2")
super().function(new_class, args)
sc = SuperClass()
sc.function()
print()
sc1 = SubClass1()
sc1.function()
print()
sc2 = SubClass2()
sc2.function()
我从示例中删除了 @overrides
装饰器,因为我认为在这种情况下它没有意义,我假设它是 this package。
【讨论】:
感谢您的示例。但是无论如何我都需要在每个类中覆盖函数def function
,因为我不想重复调用相同的函数。换句话说,我必须在每个类中获得一个被覆盖的函数。我有两个类 SuperClass 和 SubClass1 的工作逻辑。正如我所展示的,我尝试创建新的类。我想我应该提供更多信息。我将尝试编写一个工作示例。
我不确定我是否完全理解您的要求,但是用子类中的方法定义覆盖方法超类是不可能的,或者至少是您应该做的任何事情。
你是对的。这是不可能的。我认为@overrides
对我的函数做了一些事情,但这就像检查一样。 (我在问题定义末尾的def overrides(interface_class):
中提到了它)。我将在下面展示我是如何解决这个问题的......
我的代码有一个错误……我没有表明我在超类中使用了function_run()
。它还有另一个名字。我已经改变了我的问题【参考方案2】:
无法覆盖 SUBclass 中的函数。 overrides
装饰器在这里没有任何意义。我不需要覆盖一些东西。取而代之的是,我可以在函数之前直接指定需要的类(我不知道为什么,但super()
在SubClass2
中不起作用)。
这是我的解决方案:
class SuperClass:
def function(self, args: List[str] = None):
# some code
class SubClass1(SuperClass):
@overrides(SuperClass)
def function(self, args: List[str] = None):
# some code
super().function(args)
class SubClass2(SubClass2):
# @classmethod // It doesn't work as I thought
# @overrides(SubClass2) // It doesn't work as I thought
def function(self, args: List[str] = None):
# some code
SuperClass.function(self, args) # For some reason, `super()` doesn't work her
【讨论】:
以上是关于如何覆盖 SUBclass 中依次覆盖 SUPERclass 的函数(Python)?的主要内容,如果未能解决你的问题,请参考以下文章
覆盖 viewSafeAreaInsetsDidChange 需要调用 super 吗?
java中父类的方法已经被覆盖那子类还能用super关键字调用父类的方法吗
在子类中,若要调用父类中被覆盖的方法,可以使用super关键字