25 Stimmen

Wie kann ich Python-Importe verfolgen?

Ich habe zyklische Importprobleme beim Hinzufügen von neuem Code zu einer sehr großen Anwendung, und ich versuche festzustellen, welche Dateien die wahrscheinlichsten Ursachen dafür sind. Gibt es eine Möglichkeit zu verfolgen, welche Dateien welche Dateien importieren? Ich habe ein bisschen gesucht und den Python-Trace-Befehl gefunden, aber er zeigt nur eine Reihe von Aktivitäten in den Haupt-Python-Bibliotheken an.

Ich suche im Grunde nach einer App, die mir so etwas anzeigt wie:

App1 >>imports>> App2,App3.method
App2 >>imports>> App3,etc

Ich könnte einfach alle meine Dateien durchsehen, aber das möchte ich lieber nicht, es ist eine große App.

16voto

Alex Martelli Punkte 805329

Hier ist ein einfacher (und etwas rudimentärer;-) Weg, um herauszufinden, "wer versucht, was zu importieren" in Bezug auf die Modulnamen:

import inspect
import __builtin__
savimp = __builtin__.__import__

def newimp(name, *x):
  caller = inspect.currentframe().f_back
  print name, caller.f_globals.get('__name__')
  return savimp(name, *x)

__builtin__.__import__ = newimp

was zum Beispiel folgendes ergibt (ich habe dies als tracimp.py ):

$ python -c 'import tracimp; import email; import sys; import email.mime'
email __main__
sys email
email.mime email
sys __main__
email.mime __main__

Wie Sie sehen, ist ein besonderes Merkmal der "Umhüllung" der __import__ eingebaut ist, dass es nicht durch die Tatsache zum Schweigen gebracht wird, dass ein importiertes Modul bereits in sys.modules : denn das ist eine der wichtigsten Aufgaben __import__ Unser Wrapper wird für beide Module aufgerufen, die "zum ersten Mal geladen werden". y Diejenigen, die nur aus dem Internet geholt werden sys.modules weil sie bereits zuvor importiert wurden. Dies ist sehr nützlich, wenn Sie versuchen, zirkuläre Importe zu diagnostizieren (es läuft darauf hinaus, Schleifen im gerichteten Graphen zu finden, deren Kanten durch die beiden Modulnamen - importiert und importer - identifiziert werden, die bei diesem einfachen Ansatz in jeder Ausgabezeile ausgegeben werden).

12voto

unutbu Punkte 769083

Sie können eines dieser Skripte verwenden, um Python-Modul-Abhängigkeitsgraphen zu erstellen:

10voto

Ned Batchelder Punkte 342778

Versuchen Sie es mit python -v um Ihr Programm auszuführen. Es wird die Reihenfolge der Importe verfolgen.

Eine weitere Möglichkeit ist pylint die Sie auf alle möglichen Probleme aufmerksam macht, einschließlich zyklischer Importe.

-5voto

Mark Byers Punkte 761508

Es sollte nicht möglich sein, einen zyklischen Import in Python zu erhalten, weil es überprüft, ob das Modul bereits importiert wurde, bevor es erneut importiert wird. Man kann ein Modul nur einmal importieren, egal wie oft man import aufruft.

Von http://groups.google.com/group/comp.lang.python/browse_thread/thread/1d80a1c6db2b867c?pli=1 :

Importe sind ziemlich einfach wirklich. Denken Sie einfach an das Folgende:

'import' und 'from xxx import yyy' sind ausführbare Anweisungen. Sie werden ausgeführt wenn das laufende Programm diese Zeile erreicht.

Befindet sich ein Modul nicht in sys.modules, dann erzeugt ein Import den neuen Modul Eintrag in sys.modules und führt dann den den Code des Moduls aus. Er gibt nicht die Kontrolle an das aufrufende Modul zurück zurück, bis die Ausführung abgeschlossen ist.

Wenn ein Modul in sys.modules vorhanden ist vorhanden ist, gibt ein Import einfach dieses Modul zurück, unabhängig davon, ob es vollständig ausgeführt wird. Das ist der Grund, warum zyklische Importe Module zurückgeben können zurückgeben, die teilweise leer zu sein scheinen.

Schließlich läuft das ausführende Skript in einem Modul namens __main__ aus und importiert das Skripts unter seinem eigenen Namen wird ein ein neues Modul ohne Bezug zu __main__.

Nimm das alles zusammen und du sollten Sie keine Überraschungen erleben, wenn Sie Module importieren.

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