【问题标题】:How can I override the function in SUBclass that overrides the SUPERclass in turn (Python)?如何覆盖 SUBclass 中依次覆盖 SUPERclass 的函数(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 函数,是的,我导入了这个)

标签: python super overwrite


【解决方案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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-10-06
    • 2010-10-25
    • 1970-01-01
    • 2015-12-31
    • 1970-01-01
    • 1970-01-01
    • 2022-11-03
    • 2011-07-21
    相关资源
    最近更新 更多