2017-03-21 5 views
0

Wie bekomme ich die Funktion einer Elternklasse (im Gegensatz zur ungebundenen Methode)? Im folgenden Beispiel möchte ich die Funktion und die Doc-Zeichenfolge der übergeordneten Klasse abrufen. Wir haben eine Liste von Methoden (post, get) und es sollte einen passenden Funktionsnamen entweder in der Eltern- oder der Kindklasse geben. Wir müssen das Funktionsobjekt holen und seine Attribute sehen. Für die Kindklasse ist das einfach, aber ich sehe nicht, wie das für die Elternklasse zu tun ist.Wie bekomme ich Funktionen von Elternklassen? Python

Ich habe das Beispiel unten vereinfacht, aber in unserem komplexeren Fall haben wir eine große Flaschen-App, die wir umgeschrieben haben, um einen gemeinsamen Satz von Basis-/Elternklassen (mit dekorierten Funktionen) zu verwenden. Our third party library uses __dict__.get to generate swagger documentation.

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

Die Ergebnisse werden sein:

<function post at 0x1054f96e0> 
postb 
None 
None 

I Basen der Suche nach passenden Methodennamen eine Vorstellung von Iterieren B. haben. Ich bin besorgt über eine lange und tiefe Reihe von verschachtelten if- und for-Schleifen und hoffe auf eine pythischere und sauberere Lösung. dir(B) listet alle Funktionen auf, aber ich weiß nicht, wie man eine Funktion außer durch die dict greift.

Antwort

2

können Sie die magische Klasse __mro__ Methode verwenden:

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 

Dies ist jedoch die Funktion ausdrucken kann zweimal, wenn einer Ihrer Subklassen wird ein Verfahren von der übergeordneten zwingenden (nicht sicher, ob Sie sich interessieren oder es ist das, was Sie wollen)

+0

Dies scheint zu funktionieren. Ich musste 'Klasse A:' in 'Klasse A (Objekt):' ändern, um das Attribut __mro__ zu erhalten. – ytjohn

+0

Ich stieß auch auf die doppelte Methode, auf die Sie hinwiesen. Die untergeordnete Methode wird zuerst ausgeführt und anschließend in der übergeordneten Methode gedruckt. Hinzufügen einer Pause innerhalb von 'if f:' löst das auf. – ytjohn

+0

@ytjohn hat einige Änderungen hinzugefügt. Gerne können Sie meine Antwort als akzeptiert markieren :) – salparadise

Verwandte Themen