【问题标题】:python class call super's method instead of inheritedpython类调用super的方法而不是继承
【发布时间】:2017-09-08 15:07:52
【问题描述】:

我有以下问题

class A:
    def __init__(self):
        self.window = "<I am window class>"

class B(A):
    def __init__(self):
        super().__init__()

    def createObject(self):
        print(self.window)  # it works here
        self.c = C()

    def drawRect(self):
        print(self.window)  # does not work when called from class C

class C(B):
    def __init__(self):
        self.draw()

    def draw(self):
        super().drawRect()

app = B()
app.createObject()

我已经想到,当我在 C 类中调用 super().drawRect() 函数时 它将&lt;__main__.C object at 0x0000023D99FA6748&gt; 作为自我发送。

如何让 C 类在函数 draw() 中发送 &lt;__main__.B object at 0x0000017A2BA95358&gt; 中的 super().drawRect()

我之所以问是因为在非简化代码中,当我从 B 类本身调用函数时,它会打印 self.window,但是当从 C 类调用时,它会打印 None

如何解决这个问题? 我做错了什么?

【问题讨论】:

    标签: python class inheritance super self


    【解决方案1】:

    当您创建C 的实例时,没有B 对象,只有一个恰好继承自B 的C 实例。

    所以你的问题的答案:

    如何在super().drawRect() 函数draw() 中发送&lt;__main__.B object at 0x0000017A2BA95358&gt; 中的C 类

    是:你不能。

    您可以在 C 对象旁边创建一个新的 B 对象(但这会违背继承的目的)。

    但你应该在C.__init__ 中调用super().__init__ 似乎更合理:

    class C(B):
        def __init__(self):
            super().__init__()
            self.draw()
    
        def draw(self):
            super().drawRect()
    

    无论如何不这样做会很奇怪。因为继承有点暗示你扩展而不是完全覆盖。

    但考虑到您在 B.createObject 方法中执行 self.c = C() 并且 C 继承自 B,您可能应该找出另一种方式(例如 composition)而不是继承:

    class A:
        def __init__(self):
            self.window = "<I am window class>"
    
    class B(A):
        def __init__(self):
            super().__init__()
    
        def createObject(self):
            print(self.window)  # it works here
            self.c = C(self)
    
        def drawRect(self):
            print(self.window)  # does not work when called from class C
    
    class C(object):   # don't inherit from B
        def __init__(self, obj):
            self.obj = obj
            self.draw()
    
        def draw(self):
            self.obj.drawRect()
    
    app = B()
    app.createObject()
    

    但是,这将创建一个引用循环,因为您将 C 实例存储为 B 实例的属性,并将 B 实例存储为 C 实例的属性。也有可能您将代码简化了太多,也许真正的代码以某种方式阻止了组合。但是,鉴于当前代码似乎从B 继承对于您的类C 来说是一个坏主意,因为它完全覆盖Bs 行为并且不使用它的任何属性(无论如何它不能因为你覆盖了方法)。

    【讨论】:

      【解决方案2】:

      你需要打电话给

      super().__init__() 
      

      在 C 类构造函数中

      查理

      【讨论】:

        猜你喜欢
        • 2016-06-27
        • 1970-01-01
        • 2017-07-20
        • 1970-01-01
        • 1970-01-01
        • 2022-01-11
        • 2019-04-07
        • 2021-06-30
        • 1970-01-01
        相关资源
        最近更新 更多