584 Stimmen

Wie kann man alle Funktionen in einem Python-Modul auflisten?

Ich habe ein Python-Modul auf meinem System installiert und würde gerne sehen, welche Funktionen/Klassen/Methoden darin verfügbar sind.

Ich möchte die help Funktion für jeden einzelnen. In Ruby kann ich etwas tun wie ClassName.methods um eine Liste aller für diese Klasse verfügbaren Methoden zu erhalten. Gibt es etwas Ähnliches in Python?

z. B. so etwas wie:

from somemodule import foo
print(foo.methods)  # or whatever is the correct method to call

68voto

csl Punkte 10539

Der Vollständigkeit halber möchte ich noch darauf hinweisen, dass Sie manchmal zerlegen. Code, anstatt ihn zu importieren. Eine import wird ausführen. Top-Level-Ausdrücke, und das könnte ein Problem sein.

Zum Beispiel lasse ich die Benutzer Einstiegsfunktionen für Pakete auswählen, die mit zipapp . Verwendung von import y inspect die Gefahr, dass fehlerhafter Code ausgeführt wird, der zu Abstürzen führt, Hilfemeldungen ausgibt, GUI-Dialoge öffnet usw.

Stattdessen verwende ich die ast Modul, um alle Funktionen der obersten Ebene aufzulisten:

import ast
import sys

def top_level_functions(body):
    return (f for f in body if isinstance(f, ast.FunctionDef))

def parse_ast(filename):
    with open(filename, "rt") as file:
        return ast.parse(file.read(), filename=filename)

if __name__ == "__main__":
    for filename in sys.argv[1:]:
        print(filename)
        tree = parse_ast(filename)
        for func in top_level_functions(tree.body):
            print("  %s" % func.name)

Einfügen dieses Codes in list.py und sich selbst als Eingabe verwenden, erhalte ich:

$ python list.py list.py
list.py
  top_level_functions
  parse_ast

Natürlich kann die Navigation in einem AST manchmal knifflig sein, selbst bei einer relativ einfachen Sprache wie Python, da der AST recht niedrig ist. Aber wenn Sie einen einfachen und klaren Anwendungsfall haben, ist es sowohl machbar als auch sicher.

Ein Nachteil ist jedoch, dass Sie Funktionen, die zur Laufzeit generiert werden, nicht erkennen können, wie foo = lambda x,y: x*y .

5 Stimmen

Das gefällt mir; ich versuche gerade herauszufinden, ob jemand bereits ein Tool geschrieben hat, das so etwas wie pydoc macht, aber ohne das Modul zu importieren. Bis jetzt ist dies das beste Beispiel, das ich dafür gefunden habe :)

1 Stimmen

Ich stimme mit dieser Antwort überein. Ich brauche diese Funktion, damit sie funktioniert, unabhängig davon, was die Zieldatei importiert oder für welche Python-Version sie geschrieben wurde. Dies läuft nicht in die Import-Probleme, die imp und importlib tun.

0 Stimmen

Wie sieht es mit Modulvariablen ( __version__ usw.). Gibt es eine Möglichkeit, das zu bekommen?

50voto

Cireo Punkte 3840

Für Code, den Sie nicht bewerten wollen empfehle ich einen AST-basierten Ansatz (wie csl 's Antwort), z.B.:

import ast

source = open(<filepath_to_parse>).read()
functions = [f.name for f in ast.parse(source).body
             if isinstance(f, ast.FunctionDef)]

Para alles andere ist das Inspektionsmodul korrekt:

import inspect

import <module_to_inspect> as module

functions = inspect.getmembers(module, inspect.isfunction)

Dies ergibt eine Liste von 2-Tupeln in der Form [(<name:str>, <value:function>), ...] .

Die obige einfache Antwort wird in verschiedenen Antworten und Kommentaren angedeutet, aber nicht ausdrücklich genannt.

0 Stimmen

Danke für die Erklärung; ich denke, das ist die richtige Antwort, wenn Sie das Modul zur Überprüfung importieren können.

1 Stimmen

Ich musste Körper hinzufügen : ast.parse(source).body

27voto

Algorias Punkte 2947

Das wird den Zweck erfüllen:

dir(module) 

Wenn Sie es jedoch als lästig empfinden, die zurückgegebene Liste zu lesen, verwenden Sie einfach die folgende Schleife, um einen Namen pro Zeile zu erhalten.

for i in dir(module): print i

2 Stimmen

Der OP fragt eindeutig nach Funktionen, nicht nach Variablen. Siehe Antworten mit inspect . Außerdem, wie unterscheidet sich dies von @DanLenskis Antwort?

22voto

bmu Punkte 32819

dir(module) ist der Standardweg, wenn Sie ein Skript oder den Standardinterpreter verwenden, wie in den meisten Antworten erwähnt.

Aber mit einer interaktiven Python-Shell wie IPython können Sie die Registerkartenvervollständigung verwenden, um einen Überblick über alle im Modul definierten Objekte zu erhalten. Dies ist viel bequemer, als ein Skript zu verwenden und print um zu sehen, was in dem Modul definiert ist.

  • module.<tab> zeigt Ihnen alle im Modul definierten Objekte (Funktionen, Klassen usw.)
  • module.ClassX.<tab> zeigt Ihnen die Methoden und Attribute einer Klasse
  • module.function_xy? o module.ClassX.method_xy? zeigt Ihnen den Docstring dieser Funktion/Methode
  • module.function_x?? o module.SomeClass.method_xy?? zeigt Ihnen den Quellcode der Funktion/Methode.

19voto

Xantium Punkte 10070

Für globale Funktionen dir() ist der zu verwendende Befehl (wie in den meisten dieser Antworten erwähnt), der jedoch sowohl öffentliche als auch nicht-öffentliche Funktionen zusammen auflistet.

Zum Beispiel Laufen:

>>> import re
>>> dir(re)

Gibt Funktionen/Klassen wie zurück:

'__all__', '_MAXCACHE', '_alphanum_bytes', '_alphanum_str', '_pattern_type', '_pickle', '_subx'

Einige davon sind im Allgemeinen nicht für den allgemeinen Gebrauch in der Programmierung gedacht (sondern für das Modul selbst, außer im Fall von DunderAliases wie __doc__ , __file__ ect). Aus diesem Grund ist es vielleicht nicht sinnvoll, sie zusammen mit den öffentlichen aufzulisten (so weiß Python, was zu holen ist, wenn man from module import * ).

__all__ kann zur Lösung dieses Problems verwendet werden. Es gibt eine Liste aller öffentlichen Funktionen und Klassen in einem Modul zurück (diejenigen, die nicht beginnen mit Unterstrichen - _ ). Siehe Kann jemand __all__ in Python erklären? zur Verwendung von __all__ .

Hier ist ein Beispiel:

>>> import re
>>> re.__all__
['match', 'fullmatch', 'search', 'sub', 'subn', 'split', 'findall', 'finditer', 'compile', 'purge', 'template', 'escape', 'error', 'A', 'I', 'L', 'M', 'S', 'X', 'U', 'ASCII', 'IGNORECASE', 'LOCALE', 'MULTILINE', 'DOTALL', 'VERBOSE', 'UNICODE']
>>>

Alle Funktionen und Klassen mit Unterstrichen wurden entfernt, so dass nur die übrig bleiben, die als öffentlich definiert sind und daher über import * .

Beachten Sie, dass __all__ ist nicht immer definiert. Wenn sie nicht enthalten ist, wird ein AttributeError angehoben wird.

Ein Beispiel hierfür ist das Modul ast:

>>> import ast
>>> ast.__all__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: module 'ast' has no attribute '__all__'
>>>

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X