Finden, welche Methoden ein Python-Objekt hat

425

Gibt es bei einem Python-Objekt jeglicher Art eine einfache Möglichkeit, die Liste aller Methoden dieses Objekts abzurufen?

Oder,

Wenn dies nicht möglich ist, gibt es zumindest eine einfache Möglichkeit, zu überprüfen, ob es eine bestimmte Methode gibt, außer einfach zu überprüfen, ob beim Aufruf der Methode ein Fehler auftritt?

Thomas Lötzer
quelle
Relevant: stackoverflow.com/q/46033277/1959808
Ioannis Filippidis

Antworten:

521

Für viele Objekte können Sie diesen Code verwenden und 'Objekt' durch das Objekt ersetzen, an dem Sie interessiert sind:

object_methods = [method_name for method_name in dir(object)
                  if callable(getattr(object, method_name))]

Ich habe es bei diveintopython.net entdeckt (jetzt archiviert). Hoffentlich sollte das einige weitere Details liefern!

Wenn Sie eine erhalten AttributeError, können Sie diese stattdessen verwenden :

getattr(ist intolerant gegenüber python style python3.6 abstrakten virtuellen Unterklassen. Dieser Code macht das gleiche wie oben und ignoriert Ausnahmen.

import pandas as pd 
df = pd.DataFrame([[10, 20, 30], [100, 200, 300]],  
                  columns=['foo', 'bar', 'baz']) 
def get_methods(object, spacing=20): 
  methodList = [] 
  for method_name in dir(object): 
    try: 
        if callable(getattr(object, method_name)): 
            methodList.append(str(method_name)) 
    except: 
        methodList.append(str(method_name)) 
  processFunc = (lambda s: ' '.join(s.split())) or (lambda s: s) 
  for method in methodList: 
    try: 
        print(str(method.ljust(spacing)) + ' ' + 
              processFunc(str(getattr(object, method).__doc__)[0:90])) 
    except: 
        print(method.ljust(spacing) + ' ' + ' getattr() failed') 


get_methods(df['foo']) 
ljs
quelle
3
Es handelt sich um ein Listenverständnis, das eine Liste von Methoden zurückgibt, wobei method ein Element in der von dir (Objekt) zurückgegebenen Liste ist und bei der jede Methode nur dann zur Liste hinzugefügt wird, wenn getattr (Objekt, Methode) einen aufrufbaren Wert zurückgibt.
Mnebuerquo
1
Wie genau benutzt du das? Um zu sagen, drucken Sie eine Liste der Methoden.
Sumpf
12
@marsh So drucken Sie die Methoden : print [method for method in dir(object) if callable(getattr(object, method))].
Orienteerix
1
Ich bekomme eine, AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'wenn ich versuche, dies auszuführen. Weitere Informationen finden Sie unter stackoverflow.com/q/54713287/9677043 .
Karl Baker
1
funktioniert nicht für Pandas Dataframe-Objekte in Python 3.6.
Stefan Karlsson
226

Mit der integrierten dir()Funktion können Sie eine Liste aller Attribute eines Moduls abrufen. Versuchen Sie dies in der Befehlszeile, um zu sehen, wie es funktioniert.

>>> import moduleName
>>> dir(moduleName)

Sie können die hasattr(module_name, "attr_name")Funktion auch verwenden, um herauszufinden, ob ein Modul ein bestimmtes Attribut hat.

Weitere Informationen finden Sie im Handbuch zur Python-Introspektion .

Bill die Eidechse
quelle
hasattrhalf meinem Anwendungsfall, herauszufinden, ob das Python-Objekt eine bestimmte Mitgliedsvariable oder -methode hat.
Akshay
Ich bin mir nicht sicher, warum diese Lösung nicht ausreichend bewertet wird. Das ist knapp und genau.
Prasad Raghavendra
93

Die einfachste Methode ist zu verwenden dir(objectname). Es werden alle für dieses Objekt verfügbaren Methoden angezeigt. Cooler Trick.

Pawan Kumar
quelle
2
Außerdem werden die Attribute des Objekts angezeigt. Wenn Sie also gezielt nach Methoden suchen möchten, funktioniert dies nicht.
Eric
Ja. Einverstanden. Aber mir ist keine andere Technik bekannt, um nur die Liste der Methoden zu erhalten. Vielleicht ist die beste Idee, die Liste der Attribute und Methoden abzurufen und dann <hasattr (Objekt, "Methodenname">) zu verwenden, um sie weiter herauszufiltern?
Pawan Kumar
1
@neuronet, ich versuche die akzeptierte Antwort auszuführen, bekomme aber eine AttributeError: module 'pandas.core.common' has no attribute 'AbstractMethodError'. Irgendwelche Ideen? Siehe Deets unter stackoverflow.com/q/54713287/9677043 . +1 an @Pawan Kumar b / c die Antwort funktioniert und an @ljs für das Versprechen einer gefilterten Liste nur der Methoden.
Karl Baker
30

So überprüfen Sie, ob es eine bestimmte Methode gibt:

hasattr(object,"method")
Bill die Eidechse
quelle
14
Da das OP nach einer Methode sucht und nicht nur nach einem Attribut, möchte ich noch einen Schritt weiter gehen mit:if hasattr(obj,method) and callable(getattr(obj,method)):
Bruno Bronosky
28

Ich glaube, was Sie wollen, ist ungefähr so:

eine Liste von Attributen aus einem Objekt

Meiner bescheidenen Meinung nach kann die eingebaute Funktion dir()diese Aufgabe für Sie erledigen. Entnommen aus der help(dir)Ausgabe Ihrer Python-Shell:

dir (...)

dir([object]) -> list of strings

Wenn Sie ohne Argument aufgerufen werden, geben Sie die Namen im aktuellen Bereich zurück.

Andernfalls geben Sie eine alphabetische Liste von Namen zurück, die (einige) der Attribute des angegebenen Objekts und der von ihm erreichbaren Attribute enthält.

Wenn das Objekt eine benannte Methode bereitstellt __dir__, wird diese verwendet. Andernfalls wird die Standardlogik dir () verwendet und gibt Folgendes zurück:

  • für ein Modulobjekt: die Attribute des Moduls.
  • für ein Klassenobjekt: seine Attribute und rekursiv die Attribute seiner Basen.
  • für jedes andere Objekt: seine Attribute, die Attribute seiner Klasse und rekursiv die Attribute der Basisklassen seiner Klasse.

Zum Beispiel:

$ python
Python 2.7.6 (default, Jun 22 2015, 17:58:13) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.

>>> a = "I am a string"
>>>
>>> type(a)
<class 'str'>
>>>
>>> dir(a)
['__add__', '__class__', '__contains__', '__delattr__', '__doc__',
'__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__',
'__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__',
'__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__',
'__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__',
'__setattr__', '__sizeof__', '__str__', '__subclasshook__',
'_formatter_field_name_split', '_formatter_parser', 'capitalize',
'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find',
'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace',
'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition',
'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip',
'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title',
'translate', 'upper', 'zfill']

Als ich Ihr Problem überprüfte, beschloss ich, meinen Gedankengang mit einer besseren Formatierung der Ausgabe von zu demonstrieren dir().

dir_attributes.py (Python 2.7.6)

#!/usr/bin/python
""" Demonstrates the usage of dir(), with better output. """

__author__ = "ivanleoncz"

obj = "I am a string."
count = 0

print "\nObject Data: %s" % obj
print "Object Type: %s\n" % type(obj)

for method in dir(obj):
    # the comma at the end of the print, makes it printing 
    # in the same line, 4 times (count)
    print "| {0: <20}".format(method),
    count += 1
    if count == 4:
        count = 0
        print

dir_attributes.py (Python 3.4.3)

#!/usr/bin/python3
""" Demonstrates the usage of dir(), with better output. """

__author__ = "ivanleoncz"

obj = "I am a string."
count = 0

print("\nObject Data: ", obj)
print("Object Type: ", type(obj),"\n")

for method in dir(obj):
    # the end=" " at the end of the print statement, 
    # makes it printing in the same line, 4 times (count)
    print("|    {:20}".format(method), end=" ")
    count += 1
    if count == 4:
        count = 0
        print("")

Hoffe, dass ich dazu beigetragen habe :).

ivanleoncz
quelle
1
Beigetragen? Deine Antwort hat in Python 2.7.12 für mich funktioniert, also verdammt ja!
Gsamaras
23

Zusätzlich zu den direkteren Antworten wäre ich mir nicht sicher, wenn ich iPython nicht erwähnen würde . Klicken Sie auf die Registerkarte, um die verfügbaren Methoden mit automatischer Vervollständigung anzuzeigen.

Und wenn Sie eine Methode gefunden haben, versuchen Sie:

help(object.method) 

um die Pydocs, Methodensignatur usw. zu sehen.

Ahh ... REPL .

jmanning2k
quelle
12

Wenn Sie speziell Methoden wünschen , sollten Sie inspect.ismethod verwenden .

Für Methodennamen:

import inspect
method_names = [attr for attr in dir(self) if inspect.ismethod(getattr(self, attr))]

Für die Methoden selbst:

import inspect
methods = [member for member in [getattr(self, attr) for attr in dir(self)] if inspect.ismethod(member)]

Manchmal inspect.isroutinekann es auch nützlich sein (für integrierte, C-Erweiterungen, Cython ohne die Compiler-Direktive "Binding").

paulmelnikow
quelle
Sollten Sie nicht verwenden, inspect.getmembersanstatt dirin einem Listenverständnis zu verwenden?
Boris
Ja, das scheint besser zu sein!
Paulmelnikow
11

Öffnen Sie die Bash-Shell (Strg + Alt + T unter Ubuntu). Starten Sie die Python3-Shell darin. Objekt erstellen, um Methoden von zu beobachten. Fügen Sie einfach einen Punkt danach hinzu und drücken Sie zweimal die Tabulatortaste. Sie sehen so etwas:

 user@note:~$ python3
 Python 3.4.3 (default, Nov 17 2016, 01:08:31) 
 [GCC 4.8.4] on linux
 Type "help", "copyright", "credits" or "license" for more information.
 >>> import readline
 >>> readline.parse_and_bind("tab: complete")
 >>> s = "Any object. Now it's a string"
 >>> s. # here tab should be pressed twice
 s.__add__(           s.__rmod__(          s.istitle(
 s.__class__(         s.__rmul__(          s.isupper(
 s.__contains__(      s.__setattr__(       s.join(
 s.__delattr__(       s.__sizeof__(        s.ljust(
 s.__dir__(           s.__str__(           s.lower(
 s.__doc__            s.__subclasshook__(  s.lstrip(
 s.__eq__(            s.capitalize(        s.maketrans(
 s.__format__(        s.casefold(          s.partition(
 s.__ge__(            s.center(            s.replace(
 s.__getattribute__(  s.count(             s.rfind(
 s.__getitem__(       s.encode(            s.rindex(
 s.__getnewargs__(    s.endswith(          s.rjust(
 s.__gt__(            s.expandtabs(        s.rpartition(
 s.__hash__(          s.find(              s.rsplit(
 s.__init__(          s.format(            s.rstrip(
 s.__iter__(          s.format_map(        s.split(
 s.__le__(            s.index(             s.splitlines(
 s.__len__(           s.isalnum(           s.startswith(
 s.__lt__(            s.isalpha(           s.strip(
 s.__mod__(           s.isdecimal(         s.swapcase(
 s.__mul__(           s.isdigit(           s.title(
 s.__ne__(            s.isidentifier(      s.translate(
 s.__new__(           s.islower(           s.upper(
 s.__reduce__(        s.isnumeric(         s.zfill(
 s.__reduce_ex__(     s.isprintable(       
 s.__repr__(          s.isspace(           
Valery Ramusik
quelle
1
Während wir über solche Problemumgehungen sprechen, möchte ich hinzufügen, dass Sie auch ausführen ipython, das Objekt eingeben und drücken können, tabund es wird auch funktionieren. Keine Readline-Einstellungen erforderlich
Max Coplan
1
@ MaxCoplan Ich habe die Problemumgehung im Code für Fälle hinzugefügt, in denen die Tab-Vervollständigung standardmäßig nicht aktiviert ist
Valery Ramusik
8

Das Problem bei allen hier angegebenen Methoden ist, dass Sie nicht sicher sein können, dass eine Methode nicht existiert.

In Python können Sie den durch __getattr__und aufgerufenen Punkt abfangen und __getattribute__so die Methode "zur Laufzeit" erstellen.

Beispiel:

class MoreMethod(object):
    def some_method(self, x):
        return x
    def __getattr__(self, *args):
        return lambda x: x*2

Wenn Sie es ausführen, können Sie eine Methode aufrufen, die im Objektwörterbuch nicht vorhanden ist ...

>>> o = MoreMethod()
>>> o.some_method(5)
5
>>> dir(o)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattr__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'some_method']
>>> o.i_dont_care_of_the_name(5)
10

Und deshalb verwenden Sie das Einfachere, um in Python um Vergebung zu bitten, als um Erlaubnisparadigmen .

Cld
quelle
6

Der einfachste Weg, eine Liste der Methoden eines Objekts abzurufen, ist die Verwendung eines help()Befehls.

%help(object)

Es werden alle verfügbaren / wichtigen Methoden aufgelistet, die diesem Objekt zugeordnet sind.

Zum Beispiel:

help(str)
Paritosh Vyas
quelle
Was macht das %im ersten Beispiel? In meinem Python 2.7 funktioniert es nicht.
Scorchio
@Scorchio Ich habe "%" als Eingabeaufforderung anstelle von ">>>" für Python verwendet. Sie können% entfernen, bevor Sie den Befehl ausführen.
Paritosh Vyas
3
import moduleName
for x in dir(moduleName):
print(x)

Das sollte funktionieren :)

Der Mob
quelle
1

Man kann eine getAttrsFunktion erstellen , die die aufrufbaren Eigenschaftsnamen eines Objekts zurückgibt

def getAttrs(object):
  return filter(lambda m: callable(getattr(object, m)), dir(object))

print getAttrs('Foo bar'.split(' '))

Das würde zurückkehren

['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',
 '__delslice__', '__eq__', '__format__', '__ge__', '__getattribute__', 
 '__getitem__', '__getslice__', '__gt__', '__iadd__', '__imul__', '__init__', 
 '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', 
 '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', 
 '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__', 
 '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 
 'remove', 'reverse', 'sort']
james_womack
quelle
1

Es gibt keine zuverlässige Möglichkeit, alle Methoden des Objekts aufzulisten. dir(object)ist normalerweise nützlich, aber in einigen Fällen werden möglicherweise nicht alle Methoden aufgelistet. Laut dir()Dokumentation : " Versuchen Sie mit einem Argument, eine Liste gültiger Attribute für dieses Objekt zurückzugeben."

Die Überprüfung, ob eine Methode vorhanden ist, kann callable(getattr(object, method))wie dort bereits erwähnt durchgeführt werden.

behaupten
quelle
1

Nehmen Sie eine Liste als Objekt

obj = []

list(filter(lambda x:callable(getattr(obj,x)),obj.__dir__()))

Du erhältst:

['__add__',
 '__class__',
 '__contains__',
 '__delattr__',
 '__delitem__',
 '__dir__',
 '__eq__',
 '__format__',
 '__ge__',
 '__getattribute__',
 '__getitem__',
 '__gt__',
 '__iadd__',
 '__imul__',
 '__init__',
 '__init_subclass__',
 '__iter__',
 '__le__',
 '__len__',
 '__lt__',
 '__mul__',
 '__ne__',
 '__new__',
 '__reduce__',
 '__reduce_ex__',
 '__repr__',
 '__reversed__',
 '__rmul__',
 '__setattr__',
 '__setitem__',
 '__sizeof__',
 '__str__',
 '__subclasshook__',
 'append',
 'clear',
 'copy',
 'count',
 'extend',
 'index',
 'insert',
 'pop',
 'remove',
 'reverse',
 'sort']
Mahdi Ghelichi
quelle
0

... gibt es zumindest eine einfache Möglichkeit zu überprüfen, ob es eine bestimmte Methode gibt, außer einfach zu überprüfen, ob beim Aufrufen der Methode ein Fehler auftritt

Während " Einfacher um Vergebung zu bitten als um Erlaubnis " sicherlich der pythonische Weg ist, suchen Sie vielleicht nach:

d={'foo':'bar', 'spam':'eggs'}
if 'get' in dir(d):
    d.get('foo')
# OUT: 'bar'
Bruno Bronosky
quelle
0

Um in einem ganzen Modul nach einer bestimmten Methode zu suchen

for method in dir(module) :
  if "keyword_of_methode" in method :
   print(method, end="\n")
Simon PII
quelle
-1

Wenn Sie beispielsweise Shell Plus verwenden, können Sie stattdessen Folgendes verwenden:

>> MyObject??

auf diese Weise mit dem '??' Direkt nach Ihrem Objekt werden Ihnen alle Attribute / Methoden der Klasse angezeigt.

Nick Cuevas
quelle