Wie finde ich den Speicherort von Python-Modulquellen?

480

Wie erfahre ich, wo die Quelldatei für ein bestimmtes Python-Modul installiert ist? Ist die Methode unter Windows anders als unter Linux?

Ich versuche insbesondere nach der Quelle des datetimeModuls zu suchen , bin aber auch an einer allgemeineren Antwort interessiert.

Daryl Spitzer
quelle

Antworten:

375

Für ein reines Python-Modul finden Sie die Quelle unter themodule.__file__. Das datetime-Modul ist jedoch in C geschrieben und datetime.__file__verweist daher auf eine .so-Datei ( datetime.__file__unter Windows gibt es keine ). Daher können Sie die Quelle nicht sehen.

Wenn Sie einen Python-Quell-Tarball herunterladen und extrahieren, finden Sie den Code der Module im Unterverzeichnis Modules .

Wenn Sie beispielsweise den Datum / Uhrzeit-Code für Python 2.6 suchen möchten, können Sie sich diesen ansehen

Python-2.6/Modules/datetimemodule.c

Die neueste Mercurial-Version finden Sie auch im Internet unter https://hg.python.org/cpython/file/tip/Modules/_datetimemodule.c

Moe
quelle
Wenn Sie Ihre Antwort bearbeiten, um anzugeben, dass datetime .__ file__ unter Linux und Mac OS X auf .so verweist (obwohl das datetime-Modulobjekt unter Windows kein Dateiattribut hat), akzeptiere ich Ihre Antwort.
Daryl Spitzer
Eigentlich auf Windows (zumindest auf der Version ich verwende), Datetime hat einfach keine Datei - Attribut.
Daryl Spitzer
221

Wenn Sie python -vüber die Befehlszeile ausführen, sollten Sie erfahren, was von wo importiert wird. Dies funktioniert bei mir unter Windows und Mac OS X.

C:\>python -v
# installing zipimport hook
import zipimport # builtin
# installed zipimport hook
# C:\Python24\lib\site.pyc has bad mtime
import site # from C:\Python24\lib\site.py
# wrote C:\Python24\lib\site.pyc
# C:\Python24\lib\os.pyc has bad mtime
import os # from C:\Python24\lib\os.py
# wrote C:\Python24\lib\os.pyc
import nt # builtin
# C:\Python24\lib\ntpath.pyc has bad mtime
...

Ich bin mir nicht sicher, was diese schlechten Zeiten auf meiner Installation sind!

jblocksom
quelle
8
Cool! Sie können auch Ihre eigene spezifische Importanweisung eingeben, nachdem diese im interaktiven Modus geöffnet wurde, um zu sehen, woher die spezifische Bibliothek stammt.
Scorpiodawg
3
Wo sind built-inModule?
Loretoparisi
120

Mir ist klar, dass diese Antwort 4 Jahre zu spät ist, aber die vorhandenen Antworten sind irreführend.

Der richtige Weg, dies zu tun, ist niemals __file__, oder zu versuchen, durchzugehen sys.pathund nach sich selbst zu suchen usw. (es sei denn, Sie müssen ab 2.1 abwärtskompatibel sein).

Es ist das inspectModul - insbesondere getfileoder getsourcefile.

Es sei denn, Sie möchten die Regeln (die für CPython 2.x dokumentiert, aber für andere Implementierungen oder 3.x überhaupt nicht dokumentiert sind) für die Zuordnung .pyczu .pyDateien lernen und implementieren . Umgang mit .zip-Archiven, Eiern und Modulpaketen; verschiedene Wege ausprobieren, um den Pfad zu .so/ .pydDateien zu erhalten, die nicht unterstützt werden __file__; herauszufinden, was Jython / IronPython / PyPy tun; usw. In diesem Fall machen Sie es.

In der Zwischenzeit ist die Quelle jeder Python-Version ab 2.0+ online verfügbar http://hg.python.org/cpython/file/X.Y/(z. B. 2.7 oder 3.3 ). Sobald Sie feststellen, dass inspect.getfile(datetime)es sich um eine .sooder eine .pydDatei handelt /usr/local/lib/python2.7/lib-dynload/datetime.so, können Sie sie im Modulverzeichnis nachschlagen. Genau genommen gibt es keine Möglichkeit, sicher zu sein, welche Datei welches Modul definiert, aber fast alle sind entweder foo.coder foomodule.c, daher sollte es nicht schwer sein zu erraten, dass datetimemodule.c das ist, was Sie wollen.

abarnert
quelle
3
Warum gilt das __file__nicht für Nicht-Buildins? Ich verstehe, wo das Crawlen von sys.path schmerzhaft sein kann (insbesondere ohne Kenntnis von meta_path), aber ist Ihre Sorge um den Namespace zwischen __file__Definitionen und Binärdateien?
1
Ich mache dies in 2.7.8 zu datetime und erhalte nur einen TypeError für getfile und getsourcefile. Persönlich habe ich mehrere Versionen von Python installiert und ich muss wissen, auf welche Version von datetimemodule.c es zeigt, da ich im Moment weiß, dass es nicht auf die Version zeigt, auf die es angesichts der laufenden Interpreter-Version zeigen sollte ...
mmitchell
1
@mmitchell: Wenn Sie einen TypError von inspect.getfile (datetime) erhalten und davon ausgehen, dass datetime tatsächlich das Modul ist und nicht etwas anderes, das Sie demselben Namen zugewiesen haben, bedeutet dies ziemlich sicher, dass Sie einen benutzerdefinierten Build erstellt haben statische Verknüpfung in datetime mit dem Interpreter, anstatt ihn zu einem ladbaren Modul zu machen. Aber es könnte andere Gründe geben, an die ich nicht gedacht habe. Sie müssen eine neue Frage stellen und viel mehr Informationen geben, um dies zu reproduzieren.
Abarnert
@mmitchell: In der Zwischenzeit gibt es keine Möglichkeit herauszufinden, auf welche Version von datetimemodule.c es zeigt, da es nicht auf datetimemodule.c zeigt, sondern auf ein kompiliertes Modul, das aus dieser C-Datei erstellt wurde. Die C-Datei ist möglicherweise nicht auf Ihrem System vorhanden und wurde möglicherweise bearbeitet, seit Sie sie kompiliert haben.
abarnert
@tristan: Ich bin nicht sicher, ob ich verstehe, was Sie fragen, aber vielleicht wird dies darauf antworten: Wann immer __file__funktioniert, inspect.getfilefunktioniert; Es gibt keine Situation, in der das Erraten der Verwendung __file__besser ist als nur das Inspektionsmodul.
Abarnert
67

Die sys.pathListe enthält die Liste der Verzeichnisse, die zur Laufzeit nach Modulen durchsucht werden:

python -v
>>> import sys
>>> sys.path
['', '/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', ... ]
Greg Hewgill
quelle
10
python -c 'import sys; print "\n".join(sys.path)'Damit können Sie es anzeigen, ohne in interaktives Python wechseln zu müssen.
Joe Block
6
Python 3:python -c 'import sys; print("\n".join(sys.path))'
Arudzinska
61

Wenn Sie Ihre Module mit pip installieren, wird nur pip show $moduleder Speicherort zurückgegeben.

James Mark Mackenzie
quelle
10
(Ich denke, $modulees war als Platzhaltervariable gedacht, nicht wörtlich, was man m=numpy; pip show $mm
eingeben
Dies sollte als die genaueste Antwort auf die gestellte Frage markiert werden.
Rahul Goyal
37

Versuchen Sie aus der Standardbibliothek imp.find_module

>>> import imp
>>> imp.find_module('fontTools')
(None, 'C:\\Python27\\lib\\site-packages\\FontTools\\fontTools', ('', '', 5))
>>> imp.find_module('datetime')
(None, 'datetime', ('', '', 6))
Codespaced
quelle
1
Das ist fantastisch. Ich hätte apt-get removeDataDog und könnte es trotzdem importieren. Dies half mir herauszufinden, wo sich die Dateien befanden (damit ich sie löschen konnte), wenn die anderen Lösungen nicht halfen.
SG
Für Python3.x ist das impPaket (seit Version 3.4) zugunsten von importlib(seit 3.1) docs.python.org/3.6/library/imp.html
Michael,
Jetzt müssen Sie es auf diese Weise für Python3 verwenden. import importlibdannimportlib.util.find_spec('fontTools')
Medhat
33

datetime ist ein eingebautes Modul, daher gibt es keine (Python-) Quelldatei.

Für Module, die aus .py(oder .pyc) Dateien stammen, können Sie mymodule.__file__z

> import random
> random.__file__
'C:\\Python25\\lib\\random.pyc'
Bjarke Ebert
quelle
12

Im Python-Interpreter können Sie das jeweilige Modul importieren und dann help (Modul) eingeben. Dies gibt Details wie Name, Datei, Moduldokumente, Beschreibung et al.

Ex:

import os

help(os)


Help on module os:

NAME

os - OS routines for Mac, NT, or Posix depending on what system we're on.

FILE

/usr/lib/python2.6/os.py

MODULE DOCS

http://docs.python.org/library/os

DESCRIPTION

This exports:

- all functions from posix, nt, os2, or ce, e.g. unlink, stat, etc.

- os.path is one of the modules posixpath, or ntpath

- os.name is 'posix', 'nt', 'os2', 'ce' or 'riscos'

et al

Vijay
quelle
Dies gab mir einen vollständigen Pfad zur Moduldatei, während andere Antworten nur relative Pfade gaben. Vielen Dank.
Jerther
12

Hier ist ein Einzeiler, um den Dateinamen für ein Modul zu erhalten, das für das Shell-Aliasing geeignet ist:

echo 'import sys; t=__import__(sys.argv[1],fromlist=[\".\"]); print(t.__file__)'  | python - 

Als Alias ​​einrichten:

alias getpmpath="echo 'import sys; t=__import__(sys.argv[1],fromlist=[\".\"]); print(t.__file__)'  | python - "

Benutzen:

$ getpmpath twisted
/usr/lib64/python2.6/site-packages/twisted/__init__.pyc
$ getpmpath twisted.web
/usr/lib64/python2.6/site-packages/twisted/web/__init__.pyc
Ernest
quelle
9

Schauen Sie sich diesen raffinierten "cdp" -Befehl an, um in das Verzeichnis zu cd, das die Quelle für das angegebene Python-Modul enthält:

cdp () {
  cd "$(python -c "import os.path as _, ${1}; \
    print _.dirname(_.realpath(${1}.__file__[:-1]))"
  )"
}
Daryl Spitzer
quelle
Vielen Dank! Es ist genau das, wonach ich gesucht habe. Seltsamerweise würden sie so etwas nicht in die Python-Distribution aufnehmen.
Antony Hatchkins
9

Unter Windows finden Sie den Speicherort des Python-Moduls wie folgt: Suchen Sie das rest_framework-Modul Geben Sie hier die Bildbeschreibung ein

Dun0523
quelle
4

Unter Ubuntu 12.04 finden Sie beispielsweise das numpy-Paket für python2 unter:

/usr/lib/python2.7/dist-packages/numpy

Dies ist natürlich keine generische Antwort

nexayq
quelle
0

Nicht alle Python-Module sind in Python geschrieben. Datetime ist eine davon, die es nicht ist, und (unter Linux) ist datetime.so.

Sie müssten den Quellcode in die Python-Standardbibliothek herunterladen, um darauf zuzugreifen.

JimB
quelle
2
Daryl: Sie haben Jims Antwort falsch analysiert: "Datetime ist zufällig eines der Python-Module, die nicht in Python geschrieben sind."
Matthew Trevor
0

Für diejenigen, die eine GUI-Lösung bevorzugen: Wenn Sie eine GUI wie Spyder (Teil der Anaconda-Installation) verwenden, können Sie einfach mit der rechten Maustaste auf den Modulnamen klicken (z. B. "csv" in "csv importieren") und "go" auswählen zur Definition "- dies öffnet die Datei, aber auch oben können Sie den genauen Speicherort der Datei sehen (" C: .... csv.py ")

Alona
quelle
0

Wenn Sie keinen Interpreter verwenden, können Sie den folgenden Code ausführen:

import site
print (site.getsitepackages())

Ausgabe:

['C:\\Users\\<your username>\\AppData\\Local\\Programs\\Python\\Python37', 'C:\\Users\\<your username>\\AppData\\Local\\Programs\\Python\\Python37\\lib\\site-packages']

Das zweite Element in Array ist Ihr Paketspeicherort. In diesem Fall:

C:\Users\<your username>\AppData\Local\Programs\Python\Python37\lib\site-packages
Sudhee
quelle
0

Eine andere Möglichkeit, über das Terminal zu überprüfen, ob mehrere Python-Versionen installiert sind.

-MBP: ~ python3 -m pip show pyperclip

Speicherort: /Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-

MBP: ~ python -m pip show pyperclip

Speicherort: /Users/umeshvuyyuru/Library/Python/2.7/lib/python/site-packages

u_v
quelle
-1

Importieren Sie in einer IDE wie Spyder das Modul und führen Sie es dann einzeln aus. Geben Sie hier die Bildbeschreibung ein

Anirudh Sharma
quelle
Das Importieren und Drucken str()des Modells ist eine genauere Beschreibung Ihrer
Aktivitäten
2
Willkommen bei StackOverflow! Bitte geben Sie keine Postleitzahl mit Bildern ein. Bilder sind schwer zu lesen, können nicht durchsucht werden und sind für einige Leser nicht sichtbar. Fügen Sie stattdessen den relevanten Code direkt in den Text Ihrer Antwort ein.
Brian