2010-10-03 3 views
2
class A: 
    def x (self): 
     print(self.__class__) 

class B (A): 
    pass 

b = B() 
b.x() 

Dans la situation ci-dessus, est-il un moyen de la méthode x pour obtenir une référence à la classe A au lieu de B? Bien sûr écrire simplement print(A) n'est pas autorisé, car je veux ajouter quelques fonctionnalités avec un décorateur qui a besoin de la classe A (et comme je ne peux pas passer directement A au décorateur, car la classe n'existe pas encore à ce moment-là).Obtenir la classe actuelle méthode appel

+0

Chaque fois que je voulais faire cela, j'ai fini par me rendre compte que j'avais foiré le design de la classe ou que je voulais juste un Mixin ... peut-être que votre problème est le même. –

+1

Pourquoi avez-vous besoin de ça? peut-être que cela aurait dû être la question. –

+0

Eh bien, je suis sûr que je n'aurais pas besoin de ça; Fondamentalement, je voulais un décorateur de méthode qui appelle automatiquement la méthode de la super classe. Cependant, pour utiliser la classe de base correcte dans le super appel, j'ai besoin d'une référence à l'objet * current *. Je l'ai résolu maintenant cependant en réutilisant une de mes approches précédentes (échouées) et l'ai fixée avec des idées de la réponse d'Alex. – poke

Répondre

4

Sauf si vous avez super: permet d'appeler impliqués (ou plusieurs sous-classes généralement que override x et appelez directement à A.x(self) dans le cadre de la mise en œuvre de leur override), à ​​la recherche du premier élément type(self).mro() qui a un attribut x fonctionnerait -

next(c for c in type(self).mro() if hasattr(c, 'x')) 

Si vous avez besoin de couvrir super: permet d'appeler, il est plus difficile - à moins que vous connaissez qu'aucun super -class de A définit un attribut x (et bien sûr, il est plus facile de savoir vos superclasses que vos sous-classes, bien que l'héritage multiple le complique ;-) auquel cas vous avez seulement besoin du dernier du bon article du mro au lieu du premier.

+0

Bien que ce n'était pas vraiment ce dont j'avais besoin, cela m'a donné l'indice nécessaire pour résoudre mon problème, merci :) – poke

2

Vous pouvez utiliser le nom mutiler pour associer la classe une méthode est définie avec une méthode:

def set_defining_class(cls): 
    setattr(cls, '_%s__defining_class' % (cls.__name__,), cls) 
    return cls 

@set_defining_class 
class A(object): 
    def x (self): 
     print(self.__defining_class) 

@set_defining_class 
class B (A): 
    pass 


b = B() 
b.x() 

Fait ici avec un décorateur de classe, mais vous pouvez le faire à la main, ou dans une métaclasse aussi.

+0

C'est en fait une belle façon de stocker de telles informations, merci! – poke

Questions connexes