2010-04-23 5 views
0

J'ai un extrait de code comme celui-ciComment remplacer les méthodes de classe interne si la classe interne est définie comme une propriété de la classe supérieure

class A(object): 
    class b: 
     def print_hello(self): 
      print "Hello world" 
    b = property(b) 

Et je veux remplacer la classe intérieure b (s'il vous plaît ne vous inquiétez pas le nom en minuscules). Dites, je veux ajouter une nouvelle méthode ou je souhaite modifier une méthode existante, comme:

class C(A): 
    class b(A.b): 
     def print_hello(self): 
      print "Inner Class: Hello world" 
    b = property(b) 

Maintenant, si je crée l » objet C comme c = C() et appeler c.b je reçois TypeError: 'property' object is not callable error. Comment est-ce que je devrais passer ceci et appeler le print_hello de la classe interne étendue? Disclaimer: Je ne veux pas changer le code pour la classe A. Mise à jour: La classe de base 'A' essaie de simuler une classe que j'ai vue dans l'un des apis open-source. Donc c'est pourquoi je ne veux pas changer l'api de base, mais l'étendre pour ma propre exigence.

+1

Comme le dit Evgeny, quels sont les appels à la propriété() censés faire? Avec votre code d'origine, vous ne pouvez même pas faire A(). B sans avoir d'erreur. Si vous deviez décrire ce que vous essayez d'accomplir au lieu de nous donner votre solution brisée qui pourrait vous aider. – Duncan

Répondre

1

Je ne suis pas vraiment sûr pourquoi vous définiriez la classe interne comme une propriété de la classe externe. (Je ne suis pas un expert Python, alors peut-être y a-t-il une raison que je ne connais pas).

Il semble fonctionner très bien sans les propriétés:

class A(object): 
    class b: 
     def print_hello(self): 
      print "A Hello world" 

class C(A): 
    class b(A.b): 
     def print_hello(self): 
      print "C Hello world" 


outer = C() 
inner = outer.b() 
inner.print_hello() # prints "C Hello world" 
0

Chaque fois que vous accédez à la propriété « b » d'un A, une référence à la Une instance est transmise au getter - qui est ensuite passé comme argument Le constructeur de b. Cela casse votre construction dès le début, car le constructeur de b (par défaut) ne prend aucun argument supplémentaire.

Il semble que votre classe C ne fonctionne pas parce que sa classe interne 'b' hérite de l'objet de propriété 'b' de A.

Je suis curieux de savoir pourquoi vous voulez une propriété ici - il ne fait que compliquer les choses. En fait, le supprimer vous permettrait de remplacer la classe interne 'b' de A par une autre classe sur une base par instance, sans avoir à recourir à l'héritage du tout. Pouvez-vous nous donner plus d'informations avec lesquelles travailler, par ex. les intentions et le but derrière cette construction?

1

La raison pour laquelle cela échoue est que, en raison de la ligne b = property(b), A.b n'est pas la classe que vous avez définie, mais un objet de propriété. Je suis en fait un peu surpris que ça n'échoue pas sur la création de classe. Cela fonctionnerait si vous utilisiez A.b.fget comme classe de base. Mais la bonne réponse serait: ne faites pas cela. Python n'a pas de classes internes dans un sens normal, une classe définie dans la définition de classe n'est pas différente d'une classe régulière. En fait, ce code a exactement le même résultat final:

class A(object): 
    pass 

class b(object): 
    def print_hello(self): 
     print("Hello world") 

A.b = property(b) 

Je ne suis pas sûr de ce qu'il est exactement que vous essayez d'atteindre. Si je comprends bien, vous avez une classe parent qui a une propriété qui retourne des instances d'une autre classe et vous voulez avoir une sous-classe qui a une propriété qui renvoie des instances d'une sous-classe de l'autre classe. Pour sous-classer la classe retournée, vous devez obtenir une référence à cette classe pour l'utiliser comme base. Ensuite, vous pouvez simplement remplacer la propriété pour renvoyer des instances de votre sous-classe. Si vous utilisez une propriété qui recherche la classe de l'instance que vous n'avez pas réellement besoin de passer outre la définition de la propriété:

class A(object): 
    class B(object): 
     def print_hello(self): 
      print("Hello from A.B") 
    b = property(lambda self: self.B()) 

class C(A): 
    class B(A.B): 
     def print_hello(self): 
      print("Hello from C.B") 

A().b.print_hello() 
C().b.print_hello() 
Questions connexes