2017-09-08 7 views
0

j'ai le problème suivantpython méthode de super appel de classe au lieu de hérité

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

J'ai pensé que, quand je l'appelle la fonction super().drawRect() en classe C il envoie le <__main__.C object at 0x0000023D99FA6748> comme moi.

Comment puis-je faire la classe C, en fonction draw() envoyer <__main__.B object at 0x0000017A2BA95358> dans le super().drawRect()

Je demande parce que dans le code non simplifié lorsque j'appelle la fonction de la classe B lui-même, il imprime soi .window, mais lorsqu'il est appelé à partir de la classe C, il imprime Aucun

comment cela peut-il être réparé? qu'est-ce que je fais mal?

Répondre

1

Il n'y a pas d'objet B lorsque vous créez une instance de C, il n'y a qu'un exemple C qui arrive à hériter de B.

Donc, la réponse à votre question:

Comment puis-je faire la classe C, en fonction draw() envoyer <__main__.B object at 0x0000017A2BA95358> dans le super().drawRect()

est: Vous ne pouvez pas.

Vous pouvez créer un nouvel objet B (mais cela défierait le but de l'héritage) à côté de votre objet C.

Mais il semble plus raisonnable que vous devriez simplement appeler super().__init__ dans C.__init__:

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

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

Il serait bizarre de ne pas le faire de toute façon. Parce que l'héritage sorte de implique que vous étendre plutôt que remplacer complètement.

Mais compte tenu du fait que vous faites self.c = C() dans votre méthode B.createObject et C hérite de B vous devriez probablement trouver une autre façon (par exemple composition) au lieu de l'héritage:

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

Cependant, cela va créer un cycle de référence car vous stockez l'instance C comme attribut de votre instance B et l'instance B comme attribut de votre instance C. Il est également possible que vous ayez trop simplifié le code, peut-être que le code réel empêche la composition d'une manière ou d'une autre. Toutefois, étant donné le code actuel, il semble que l'héritage de B est une mauvaise idée pour votre classe C étant donné qu'il remplace complètement le comportement de B et n'utilise aucun de ses attributs (ce qu'il ne peut pas faire parce que vous avez outrepassé les méthodes).

0

vous devez appeler à

super().__init__() 

dans le constructeur de classe C

Charlie