Comment trouver l'emplacement des sources du module Python?

481

Comment savoir où est installé le fichier source d'un module Python donné? La méthode est-elle différente sous Windows que sous Linux?

J'essaie de rechercher la source du datetimemodule en particulier, mais je suis également intéressé par une réponse plus générale.

Daryl Spitzer
la source

Réponses:

375

Pour un module pur python, vous pouvez trouver la source en regardant themodule.__file__. Le module datetime, cependant, est écrit en C, et datetime.__file__pointe donc vers un fichier .so (il n'y en a pas datetime.__file__sous Windows), et par conséquent, vous ne pouvez pas voir la source.

Si vous téléchargez une archive tar source python et que vous l'extrayez, le code des modules se trouve dans le sous-répertoire Modules .

Par exemple, si vous voulez trouver le code datetime pour python 2.6, vous pouvez regarder

Python-2.6/Modules/datetimemodule.c

Vous pouvez également trouver la dernière version de Mercurial sur le Web à l' adresse https://hg.python.org/cpython/file/tip/Modules/_datetimemodule.c

Moe
la source
Si vous modifiez votre réponse pour indiquer que datetime .__ file__ pointe vers un .so sous Linux et Mac OS X (bien que sous Windows, l'objet module datetime n'a pas d' attribut de fichier ), j'accepte votre réponse.
Daryl Spitzer
En fait sous Windows (au moins sur la version que j'utilise), datetime n'a tout simplement pas d' attribut de fichier .
Daryl Spitzer
221

L'exécution à python -vpartir de la ligne de commande devrait vous indiquer ce qui est importé et d'où. Cela fonctionne pour moi sur Windows et 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
...

Je ne sais pas quels sont ces mauvais mtime sur mon installation!

jblocksom
la source
8
Cool! Vous pouvez également taper votre propre instruction d'importation spécifique après son ouverture en mode interactif pour voir d'où vient la bibliothèque spécifique.
scorpiodawg
3
Où sont les built-inmodules?
loretoparisi
120

Je me rends compte que cette réponse a 4 ans de retard, mais les réponses existantes trompent les gens.

La bonne façon de le faire n'est jamais __file__, ou d'essayer de se promener sys.pathet de se rechercher, etc. (sauf si vous devez être rétrocompatible au-delà de 2.1).

C'est le inspectmodule, en particulier, getfileou getsourcefile.

À moins que vous ne vouliez apprendre et implémenter les règles (qui sont documentées, mais pénibles, pour CPython 2.x, et pas du tout documentées pour les autres implémentations, ou 3.x) pour le mappage .pycaux .pyfichiers; gérer les archives .zip, les œufs et les packages de modules; essayer différentes façons d'obtenir le chemin d'accès aux fichiers .so/ .pydqui ne sont pas pris en charge __file__; comprendre ce que font Jython / IronPython / PyPy; etc. Dans ce cas, allez-y.

Pendant ce temps, la source de chaque version Python de 2.0+ est disponible en ligne à http://hg.python.org/cpython/file/X.Y/(par exemple, 2.7 ou 3.3 ). Ainsi, une fois que vous découvrez qu'il inspect.getfile(datetime)s'agit d'un fichier .soou , vous pouvez le rechercher dans le répertoire Modules. À strictement parler, il n'y a aucun moyen de savoir quel fichier définit quel module, mais presque tous sont soit ou , donc il ne devrait pas être difficile de deviner que datetimemodule.c est ce que vous voulez..pyd/usr/local/lib/python2.7/lib-dynload/datetime.sofoo.cfoomodule.c

abarnert
la source
3
Pourquoi le n'est __file__pas applicable pour les non-intégrés? Je comprends où l'exploration de sys.path peut être douloureuse (en particulier sans connaître meta_path), mais est-ce que vous vous inquiétez de l'espace de noms entre les __file__définitions et les binaires?
1
Je fais cela dans 2.7.8 sur datetime et j'obtiens juste un TypeError pour getfile et getsourcefile. Personnellement, j'ai plusieurs versions de python installées et j'ai besoin de savoir QUELLE version de datetimemodule.c vers laquelle il pointe, car pour le moment je sais qu'il ne pointe pas vers celle vers laquelle il devrait être pointé étant donné la version de l'interpréteur qui s'exécute ...
mmitchell
1
@mmitchell: Si vous obtenez une TypeError de inspect.getfile (datetime), en supposant que datetime est en fait le module et pas autre chose que vous avez attribué au même nom, je suis presque sûr que cela signifie que vous avez fait une construction personnalisée pour lier statiquement dans datetime à l'interpréteur au lieu d'en faire un module chargeable. Mais il pourrait y avoir d'autres raisons auxquelles je n'ai pas pensé. Vous devez poser une nouvelle question et donner beaucoup plus d'informations pour la reproduire.
abarnert
@mmitchell: Pendant ce temps, il n'y a aucun moyen de savoir sur quelle version de datetimemodule.c il pointe, car il ne pointe pas sur datetimemodule.c, il pointe sur un module compilé construit à partir de ce fichier C; le fichier C peut ne pas exister sur votre système, peut avoir été modifié depuis que vous l'avez compilé, peu importe.
abarnert
@tristan: Je ne suis pas sûr de comprendre ce que vous demandez, mais peut-être que cela répondra: chaque fois que ça __file__marche, ça inspect.getfilemarche; il n'y a aucune situation où deviner s'il faut utiliser __file__sera mieux que d'utiliser simplement le module d'inspection.
abarnert
67

La sys.pathliste contient la liste des répertoires qui seront recherchés pour les modules lors de l'exécution:

python -v
>>> import sys
>>> sys.path
['', '/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', ... ]
Greg Hewgill
la source
10
python -c 'import sys; print "\n".join(sys.path)'vous permettra de le visualiser sans avoir à passer en python interactif.
Joe Block
6
Python 3:python -c 'import sys; print("\n".join(sys.path))'
arudzinska
61

Si vous utilisez pip pour installer vos modules, seul pip show $modulel'emplacement est retourné.

James Mark Mackenzie
la source
10
(Je pense $modulea été conçue comme une variable d'espace réservé, pas littéralement ce que l' on taperait par exemple. m=numpy; pip show $m... etc, pour tout m)
michael
cela devrait être marqué comme la réponse la plus précise à la question posée.
Rahul Goyal
37

à partir de la bibliothèque standard, essayez 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))
Codepaced
la source
1
C'est fantastique. J'aurais apt-get removeDataDog et je pourrais encore l'importer. Cela m'a aidé à trouver où se trouvaient les fichiers (afin que je puisse les supprimer) lorsque les autres solutions n'ont pas aidé.
sg
pour python3.x, le imppaquet est déconseillé (depuis la version 3.4) en faveur de importlib(depuis 3.1) docs.python.org/3.6/library/imp.html
michael
Vous devez maintenant l'utiliser de cette manière pour python3. import importlibpuisimportlib.util.find_spec('fontTools')
Medhat
34

datetime est un module intégré, il n'y a donc pas de fichier source (Python).

Pour les modules provenant de .py(ou .pyc) fichiers, vous pouvez utiliser mymodule.__file__, par exemple

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

Dans l'interpréteur python, vous pouvez importer le module particulier, puis taper help (module). Cela donne des détails tels que le nom, le fichier, la documentation du module, la description 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
la source
Cela m'a donné un chemin complet vers le fichier du module tandis que d'autres réponses ne donnaient que des chemins relatifs. Merci.
Jerther
12

Voici une ligne pour obtenir le nom de fichier d'un module, adapté à l'alias de shell:

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

Configuré comme alias:

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

Utiliser:

$ 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
la source
9

Consultez cette astucieuse commande "cdp" pour accéder au répertoire contenant la source du module Python indiqué:

cdp () {
  cd "$(python -c "import os.path as _, ${1}; \
    print _.dirname(_.realpath(${1}.__file__[:-1]))"
  )"
}
Daryl Spitzer
la source
Merci! C'est juste ce que je cherchais. Assez curieusement, ils n'incluraient pas quelque chose du genre dans la distribution de python.
Antony Hatchkins
9

Sur les fenêtres, vous pouvez trouver l'emplacement du module python comme indiqué ci-dessous: ie trouver le module rest_framework entrez la description de l'image ici

Dun0523
la source
4

Sur Ubuntu 12.04, par exemple le paquet numpy pour python2, peut être trouvé à:

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

Bien sûr, ce n'est pas une réponse générique

nexayq
la source
0

Tous les modules python ne sont pas écrits en python. Datetime se trouve être l'un d'entre eux qui ne l'est pas, et (sous Linux) est datetime.so.

Vous devriez télécharger le code source dans la bibliothèque standard de python pour y accéder.

JimB
la source
2
Daryl: Vous avez mal interprété la réponse de Jim, "Datetime se trouve être l'un des modules python non écrits en python".
Matthew Trevor
0

Pour ceux qui préfèrent une solution graphique: si vous utilisez une interface graphique telle que Spyder (faisant partie de l'installation d'Anaconda), vous pouvez simplement cliquer avec le bouton droit sur le nom du module (tel que "csv" dans "import csv") et sélectionner "aller to definition "- cela ouvrira le fichier, mais aussi en haut vous pouvez voir l'emplacement exact du fichier (" C: .... csv.py ")

Alona
la source
0

Si vous n'utilisez pas d'interpréteur, vous pouvez exécuter le code ci-dessous:

import site
print (site.getsitepackages())

Production:

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

Le deuxième élément dans Array sera l'emplacement de votre package. Dans ce cas:

C:\Users\<your username>\AppData\Local\Programs\Python\Python37\lib\site-packages
sudhee
la source
0

Une autre façon de vérifier si plusieurs versions de python sont installées depuis le terminal.

-MBP: ~ python3 -m pip afficher pyperclip

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

MBP: ~ python -m pip afficher pyperclip

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

u_v
la source
-1

Dans un IDE comme Spyder, importez le module, puis exécutez le module individuellement. entrez la description de l'image ici

Anirudh Sharma
la source
Importer et imprimer le str()modèle est une description plus précise de ce que vous faites dans la capture d'écran, plus l'EDI ne semble pas pertinent pour cette solution
queue de souris
2
Bienvenue sur StackOverflow! Veuillez ne pas publier de code à l'aide d'images. Les images sont difficiles à lire, ne peuvent pas être recherchées et ne sont pas visibles par certains lecteurs. Veuillez plutôt inclure tout code pertinent directement dans le corps de votre réponse.
Brian