简体   繁体   English

python类调用super的方法,而不是继承的

[英]python class call super's method instead of inherited

I have the following problem 我有以下问题

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

I have figured that, when I call the super().drawRect() function in class C it sends the <__main__.C object at 0x0000023D99FA6748> as self. 我已经弄清楚,当我在类C中调用super().drawRect()函数时,它会将<__main__.C object at 0x0000023D99FA6748>作为自身。

How can I make class C, in function draw() send <__main__.B object at 0x0000017A2BA95358> in the super().drawRect() 我如何使类C在函数draw()中在super().drawRect()发送<__main__.B object at 0x0000017A2BA95358>

I am asking because in the non-simplified code when I call the function from the B class itself, it prints the self.window, but when called from the C class it prints None 我问是因为在非简化代码中,当我从B类本身调用函数时,它会打印self.window,但是从C类中调用时,它会打印None

how can this be fixed? 如何解决? what am I doing wrong? 我究竟做错了什么?

There is no B object when you create an instance of C , there is only a C instance that happens to inherit from B . 创建C的实例时没有B对象,只有一个C实例恰巧是从B继承的。

So the answer to your question: 因此,您的问题的答案是:

How can I make class C, in function draw() send <__main__.B object at 0x0000017A2BA95358> in the super().drawRect() 我如何使类C在函数draw()中在super().drawRect()发送<__main__.B object at 0x0000017A2BA95358>

Is: You can't. 是:不能。

You could create a new B object (but that would defy the purpose of inheritance) alongside your C object. 您可以在C对象的旁边创建一个新的B对象(但这会违背继承的目的)。

But it seems more reasonable that you should just call super().__init__ in C.__init__ : 但是,应该只在C.__init__调用super().__init__似乎更合理:

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

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

It would be weird not to do that anyway. 无论如何不要这样做会很奇怪。 Because inheritance sort of implies that you extend rather than override completely . 因为继承意味着您要扩展而不是完全覆盖

But given the fact that you do self.c = C() in your B.createObject method and C inherits from B you should probably figure out another way (eg composition ) instead of inheritance: 但是考虑到您在B.createObject方法中执行self.c = C()并且CB继承的事实,您可能应该找出另一种方式(例如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()

However this will create a reference cycle because you store the C instance as attribute of your B instance and the B instance as attribute of your C instance. 但是因为你存储,这将创建一个参考周期C实例作为您的属性B实例和B实例作为您的属性C实例。 It's also possible that you simplified the code too much, maybe the real code prevents composition in some way. 您也可能过于简化了代码,也许真实的代码以某种方式阻止了合成。 However given the current code it seems like inheriting from B is a bad idea for your class C given that it overrides B s behavior completely and doesn't use any of it's attributes (which it can't anyway because you overrode the methods). 但是,考虑到当前代码,从类B继承似乎对您的类C是一个坏主意,因为它完全覆盖了B的行为并且不使用其任何属性(由于您覆盖了方法,因此无论如何也不能这样做)。

you need to call to 您需要致电

super().__init__() 

in class C constructor 在C类构造函数中

Charlie 查理

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM