2009-12-15 2 views
198

Ich möchte die Methoden in einer Klasse durchlaufen oder Klassen- oder Instanzobjekte basierend auf den vorhandenen Methoden unterschiedlich behandeln. Wie bekomme ich eine Liste von Klassenmethoden?Wie bekomme ich eine Liste von Methoden in einer Python-Klasse?

Siehe auch:

+38

@ S.Lott Warum können Sie nicht die Macht benutzen? Was ist los mit der Macht? – jononomo

+0

Die Quelle ..... die Quelle ... – RickyA

+0

@JonCrowell das ist nicht, wie die Macht funktioniert. –

Antwort

225

Ein Beispiel (Listing die Methoden der optparse.OptionParser Klasse):

>>> from optparse import OptionParser 
>>> import inspect 
>>> inspect.getmembers(OptionParser, predicate=inspect.ismethod) 
[([('__init__', <unbound method OptionParser.__init__>), 
... 
('add_option', <unbound method OptionParser.add_option>), 
('add_option_group', <unbound method OptionParser.add_option_group>), 
('add_options', <unbound method OptionParser.add_options>), 
('check_values', <unbound method OptionParser.check_values>), 
('destroy', <unbound method OptionParser.destroy>), 
('disable_interspersed_args', 
    <unbound method OptionParser.disable_interspersed_args>), 
('enable_interspersed_args', 
    <unbound method OptionParser.enable_interspersed_args>), 
('error', <unbound method OptionParser.error>), 
('exit', <unbound method OptionParser.exit>), 
('expand_prog_name', <unbound method OptionParser.expand_prog_name>), 
... 
] 

Beachten Sie, dass getmembers eine Liste von 2-Tupeln zurückgibt. Das erste Element ist der Name des Mitglieds, das zweite Element ist der Wert.

>>> parser = OptionParser() 
>>> inspect.getmembers(parser, predicate=inspect.ismethod) 
... 
+3

Perfekt, der Prädikat-Teil ist der Schlüssel, sonst erhalten Sie das gleiche wie __dict__ mit den zusätzlichen Meta-Informationen. Vielen Dank. – Purrell

+1

Wird dadurch eine Liste aller Methoden in der Klasse erstellt (einschließlich derer, die von anderen Klassen geerbt werden) oder werden nur die Methoden aufgelistet, die in dieser Klasse explizit definiert sind? –

+0

Es enthält vererbte Methoden. – codeape

22

Versuchen Sie, die Eigenschaft __dict__:

Sie können auch eine Instanz getmembers passieren.

+11

Ich denke, du meinst __dict__. Aber das listet die Attribute der Instanz auf, nicht die Methoden. –

+1

... das hat auch nicht für mich funktioniert. Nachdem ich die Markdown-Syntax konsultiert habe, denke ich, ich meine \ _ \ _ dict \ _ \ _. –

+2

@me_and du machst wahrscheinlich "self .__ dict__" oder, allgemeiner gesagt, rufe die Instanzversion von '__dict__' auf. Aber Klassen haben auch ein "__dict__" und das sollte die Klassenmethoden anzeigen :) – Seaux

129

Es ist die dir(theobject) Methode, um alle Felder und Methoden des Objekts zur Liste (als Tupel) und das Modul überprüfen (wie codeape Schreiben) auf die Felder und Methoden mit ihrer doc zur Liste (in „“ ").

Weil alles (auch Felder) könnte in Python genannt werden, ich bin nicht sicher, ob es eine eingebaute Funktion ist nur Methoden zur Liste. Sie könnten versuchen wollen, wenn das Objekt Sie dir erhalten durch callable ist oder nicht .

9

Beachten Sie, dass Sie berücksichtigen müssen, ob Sie Methoden von Basisklassen wollen, die vererbt (aber nicht überschrieben) werden im Ergebnis. Die Operationen dir() und inspect.getmembers() schließen Basisklassenmethoden ein, die Verwendung des Attributs __dict__ jedoch nicht.

0
def find_defining_class(obj, meth_name): 
    for ty in type(obj).mro(): 
     if meth_name in ty.__dict__: 
      return ty 

So

print find_defining_class(car, 'speedometer') 

Denken Python Seite 210

+2

Einrückung von 5? Großschreibung von Keywords? Nicht-Pep8-Stil Abstand? – towerofnix

+0

Nicht einmal die Kodierungskonvention Nazis ist dazu gekommen! – rbennell

-1

Ich weiß, dass dies eine alte Post, aber gerade geschrieben habe diese Funktion und es wird hier verlassen wird, falls jemand stolpert für eine Suche Antwort:

def classMethods(the_class,class_only=False,instance_only=False,exclude_internal=True): 

    def acceptMethod(tup): 
     #internal function that analyzes the tuples returned by getmembers tup[1] is the 
     #actual member object 
     is_method = inspect.ismethod(tup[1]) 
     if is_method: 
      bound_to = tup[1].im_self 
      internal = tup[1].im_func.func_name[:2] == '__' and tup[1].im_func.func_name[-2:] == '__' 
      if internal and exclude_internal: 
       include = False 
      else: 
       include = (bound_to == the_class and not instance_only) or (bound_to == None and not class_only) 
     else: 
      include = False 
     return include 
    #uses filter to return results according to internal function and arguments 
    return filter(acceptMethod,inspect.getmembers(the_class)) 
+0

Dieser Code funktioniert nicht so, wie er veröffentlicht wurde. Wenn class_only oder instance_only angegeben wird, führt dies zu einer leeren Liste. – Oz123

10

können Sie auch importieren Function von Arten und testen Sie es mit dem class.__dict__:

from types import FunctionType 

class Foo: 
    def bar(self): pass 
    def baz(self): pass 

def methods(cls): 
    return [x for x, y in cls.__dict__.items() if type(y) == FunctionType] 

methods(Foo) # ['bar', 'baz'] 
+0

Das hat gut für mich funktioniert. Ich habe '' und nicht x.startswith ('_') 'am Ende des Listenverständnisses hinzugefügt, damit ich'___init_'s und private Methoden ignorieren kann. –

+1

Sie können den 'Import' von' FunctionType' umgehen, indem Sie ein Wegwerf-Lambda mit 'type()' verwenden: 'type (lambda: 0)' – Tersosauros

30

Python 3.x Antwort ohne externe Bibliotheken

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func))] 

dunder ausgeschlossenen Ergebnis:

method_list = [func for func in dir(Foo) if callable(getattr(Foo, func)) and not func.startswith("__")] 
Verwandte Themen