2017-03-21 1 views
0

Comment puis-je obtenir la fonction d'une classe parent (par opposition à la méthode non liée)? Dans l'exemple ci-dessous, j'aimerais obtenir la fonction et la chaîne doc de la classe parente. Nous avons une liste de méthodes (post, get) et il devrait y avoir un nom de fonction correspondant dans la classe parent ou enfant. Nous devons obtenir l'objet fonction et voir ses attributs. Pour la classe enfant, c'est facile, mais je ne vois pas comment le faire pour la classe parente. J'ai simplifié l'exemple ci-dessous, mais dans notre cas plus complexe, nous avons une grande application flask que nous avons réécrite pour utiliser un ensemble commun de classes de base/parent (avec des fonctions décorées). Our third party library uses __dict__.get to generate swagger documentation.comment obtenir les fonctions des classes parentes python

class A(): 

    def get(self): 
     """geta""" 
     desc = 'geta' 
     print('got it') 


class B(A): 

    def post(self): 
     """postb""" 
     desc = 'postb' 
     print('posted') 


# this is the part we need to change: 
methods = ['post', 'get'] 
for method in methods: 
    f = B.__dict__.get(method, None) 
    print(f) 
    print(f.__doc__) 

Les résultats seront:

<function post at 0x1054f96e0> 
postb 
None 
None 

J'ai une idée de itérer B. bases recherche pour faire correspondre les noms de méthode. Je suis inquiet au sujet d'un ensemble long et profond de si et de boucles imbriquées, et j'espère une solution plus pythonique et propre. dir(B) répertorie toutes les fonctions, mais je ne sais pas comment attraper une fonction sauf à travers le dict.

Répondre

2

Vous pouvez utiliser la méthode magique classe __mro__:

In [3]: class A: #(object) if using 2.x 
    ...:  def post(s): 
    ...:   """foo""" 
    ...:   pass 
    ...: 
    ...: 

In [4]: class B(A): 
    ...:  def get(s): 
    ...:   """boo""" 
    ...:   pass 
    ...: 

In [8]: methods = ['get', 'post'] 


In [10]: for m in methods: 
    ...:  for c in B.__mro__: 
    ...:   f = c.__dict__.get(m) 
    ...:   if f: 
    ...:    print(f) 
    ...:    print(f.__doc__) 
        break # if you don't want duplicate functions 
          # (with subclass listed first) 
    ...: 
<function B.get at 0x102ece378> 
boo 
<function A.post at 0x102ee8730> 
foo 

Toutefois, cela peut imprimer la fonction deux fois si l'un de vos sous-classes est prépondérant une méthode de son parent (ne sais pas si vous vous souciez ou il est ce que vous voulez)

+0

Cela semble fonctionner. J'ai dû changer la classe A: 'en' la classe A (objet): 'pour obtenir l'attribut __mro__. – ytjohn

+0

J'ai également rencontré la méthode du doublon que vous avez suggérée. Il fait d'abord la méthode enfant, puis imprime celle de la méthode parent. Ajouter une pause à l'intérieur de 'if f:' résout cela. – ytjohn

+0

@ytjohn a ajouté quelques modifications. Vous êtes invités à marquer ma réponse comme acceptée :) – salparadise