如何覆盖 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 方法会很有帮助。 也许overridespytests 的一部分,所以我不使用导入。我对 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关键字

当覆盖 initWithCoder 时,总是需要调用 [super initWithCoder: coder]

[Java] 继承中,父类被覆盖的成员变量方法的可访问性