2017-09-08 143 views
0

我有以下問題蟒蛇類調用超類的方法,而不是繼承

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()功能,它發送<__main__.C object at 0x0000023D99FA6748>自我。

我怎樣才能讓C類,函數平局()在super().drawRect()

我問,因爲在非精簡代碼時,我調用該函數從B類自身發送<__main__.B object at 0x0000017A2BA95358>,它打印的自.window,但是當從C類調用時,它會打印無

這怎麼解決? 我做錯了什麼?

回答

1

沒有B對象時創建的C一個實例,只有恰巧從B繼承C實例。

所以回答你的問題:

我怎樣才能讓C類,在功能draw()super().drawRect()

發送<__main__.B object at 0x0000017A2BA95358>是:你不能。

您可以創建一個新的B對象(但這不符合繼承的目的)與您的C對象一起。

但似乎更爲合理,你應該只調用super().__init__C.__init__

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

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

這將是不可思議不這樣做呢。因爲繼承的意思是你延伸而不是完全覆蓋

但鑑於您在B.createObject方法做self.c = C()BC繼承你應該找出另一種方式(如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是一個糟糕的主意,因爲它完全覆蓋B的行爲,並沒有使用它的任何屬性(因爲您覆蓋了方法而無法執行),因此對您的類C來說是一個糟糕的主意。

0

你需要在C類的構造函數調用到

super().__init__() 

查理