Angenommen, ich habe eine Python-Funktion wie unten definiert:
def foo(arg1,arg2):
#do something with args
a = arg1 + arg2
return a
Ich kann den Namen der Funktion mit abrufen foo.func_name
. Wie kann ich den Quellcode programmgesteuert abrufen, wie ich oben eingegeben habe?
foo.__name__
Antworten:
Wenn die Funktion aus einer im Dateisystem verfügbaren Quelldatei stammt,
inspect.getsource(foo)
kann dies hilfreich sein:If
foo
ist definiert als:Dann:
Kehrt zurück:
Ich glaube jedoch, dass Sie den Quellcode nicht abrufen können, wenn die Funktion aus einer Zeichenfolge kompiliert, gestreamt oder aus einer kompilierten Datei importiert wird.
quelle
len
. Wo finde ich den Quellcode für dielen
Funktion?inspect.getsourcelines(foo)
Das Inspect-Modul verfügt über Methoden zum Abrufen von Quellcode aus Python-Objekten. Scheinbar funktioniert es nur, wenn sich die Quelle in einer Datei befindet. Wenn Sie das hätten, müssten Sie wahrscheinlich nicht die Quelle vom Objekt abrufen.
quelle
python 3.5.3
Dolmetscher zu verwenden.import inspect
+ hat gutinspect.getsource(foo)
funktioniert.dis
ist dein Freund, wenn der Quellcode nicht verfügbar ist:quelle
Wenn Sie IPython verwenden, müssen Sie "foo ??"
quelle
dir(MyClass)
dannMyClass.__init__??
und so weiter.Obwohl ich im Allgemeinen zustimmen würde, dass dies
inspect
eine gute Antwort ist, würde ich nicht zustimmen, dass Sie den Quellcode der im Interpreter definierten Objekte nicht erhalten können. Wenn Siedill.source.getsource
von verwendendill
, können Sie die Quelle von Funktionen und Lambdas abrufen, auch wenn diese interaktiv definiert sind. Es kann auch den Code für gebundene oder ungebundene Klassenmethoden und -funktionen abrufen, die in Currys definiert sind. Möglicherweise können Sie diesen Code jedoch nicht ohne den Code des umschließenden Objekts kompilieren.quelle
dill.source.getsource
Überprüft den Verlauf des Interpreters auf Funktionen, Klassen, Lambdas usw. - Der Inhalt der an exec übergebenen Zeichenfolgen wird nicht überprüft.dill
diese Frage zu beantworten: stackoverflow.com/questions/13827543/…dill.source
hat Funktionen wiegetname
undimportable
undgetsource
, die sich darauf konzentrieren, den Quellcode (oder einen importierbaren Code, der das Objekt liefert) für ein bestimmtes Objekt abzurufen. Für einfache Dinge wie aint
gibt es keine Quelle, daher funktioniert es nicht wie erwartet (dh für 'a = 10' wird '10' zurückgegeben).>>> a = 10; print( [key for key, val in globals().items() if val is a][0] )
dill
, aber meine Antwort lässt etwas zu wünschen übrig (IE, wenn Sie mehrere Namen für denselben Wert haben, kann es nicht herausfinden, welche verwendet wurden. Wenn Sie Wenn Sie einen Ausdruck übergeben, kann er nicht sagen, was dieser Ausdruck war. Wenn Sie einen Ausdruck übergeben, der den gleichen Wert wie ein Name hat, wird stattdessen dieser Name angegeben.) Kanndill
einen dieser Mängel meiner Antwort beheben hier: stackoverflow.com/a/28634996/901641Um die Antwort von runeh zu erweitern:
BEARBEITEN: Wie von @ 0sh hervorgehoben, funktioniert dieses Beispiel mit,
ipython
aber nicht einfachpython
. Es sollte jedoch in beiden Fällen in Ordnung sein, wenn Code aus Quelldateien importiert wird.quelle
getsource(foo)
.Sie können das
inspect
Modul verwenden, um den vollständigen Quellcode dafür zu erhalten. Sie müssen dafür diegetsource()
Methode aus deminspect
Modul verwenden. Zum Beispiel:Weitere Optionen finden Sie unter dem folgenden Link. Rufen Sie Ihren Python-Code ab
quelle
Da dieser Beitrag als Duplikat dieses anderen Beitrags markiert ist , antworte ich hier für den Fall "Lambda", obwohl es im OP nicht um Lambdas geht.
Für Lambda-Funktionen, die nicht in eigenen Zeilen definiert sind: Zusätzlich zur Antwort von marko.ristin möchten Sie möglicherweise Mini-Lambda oder SymPy verwenden, wie in dieser Antwort vorgeschlagen .
mini-lambda
ist leichter und unterstützt jede Art von Operation, funktioniert aber nur für eine einzelne VariableSymPy
ist schwerer, aber viel besser mit mathematischen / Kalküloperationen ausgestattet. Insbesondere kann es Ihre Ausdrücke vereinfachen. Es werden auch mehrere Variablen im selben Ausdruck unterstützt.So können Sie es machen mit
mini-lambda
:Es gibt richtig nach
Einzelheiten finden Sie in der
mini-lambda
Dokumentation . Ich bin übrigens der Autor;)quelle
Bitte beachten Sie, dass die akzeptierten Antworten nur funktionieren, wenn das Lambda in einer separaten Zeile angegeben wird. Wenn Sie es als Argument an eine Funktion übergeben und den Code des Lambda als Objekt abrufen möchten, wird das Problem etwas schwierig, da
inspect
Sie die gesamte Zeile erhalten.Betrachten Sie beispielsweise eine Datei
test.py
:Wenn Sie es ausführen, erhalten Sie (beachten Sie die Einrückung!):
Um den Quellcode des Lambda abzurufen, ist es meiner Meinung nach am besten, die gesamte Quelldatei (mithilfe von
f.__code__.co_filename
) erneut zu analysieren und den Lambda-AST-Knoten anhand der Zeilennummer und seines Kontexts abzugleichen.Genau das mussten wir in unserer Design-by-Contract-Bibliothek icontract tun, da wir die Lambda-Funktionen analysieren mussten, die wir als Argumente an Dekorateure übergeben. Es ist zu viel Code, um ihn hier einzufügen. Schauen Sie sich also die Implementierung dieser Funktion an .
quelle
Wenn Sie die Funktion streng selbst definieren und es sich um eine relativ kurze Definition handelt, besteht eine Lösung ohne Abhängigkeiten darin, die Funktion in einer Zeichenfolge zu definieren und Ihrer Funktion das eval () des Ausdrucks zuzuweisen.
Z.B
dann optional, um den Originalcode an die Funktion anzuhängen:
quelle
zusammenfassen :
quelle
Ich glaube, dass Variablennamen nicht in pyc / pyd / pyo-Dateien gespeichert sind, so dass Sie die genauen Codezeilen nicht abrufen können, wenn Sie keine Quelldateien haben.
quelle