Bagaimana cara menemukan lokasi sumber modul Python?

481

Bagaimana saya belajar di mana file sumber untuk modul Python tertentu diinstal? Apakah metode ini berbeda di Windows daripada di Linux?

Saya mencoba mencari sumber datetimemodul khususnya, tetapi saya tertarik pada jawaban yang lebih umum juga.

Daryl Spitzer
sumber

Jawaban:

375

Untuk modul python murni, Anda dapat menemukan sumbernya dengan melihatnya themodule.__file__. Modul datetime, bagaimanapun, ditulis dalam C, dan karena itu datetime.__file__menunjuk ke file .so (tidak ada datetime.__file__pada Windows), dan karena itu, Anda tidak dapat melihat sumbernya.

Jika Anda mengunduh tarball sumber python dan mengekstraknya, kode modul dapat ditemukan di subdirektori Modul .

Misalnya, jika Anda ingin menemukan kode datetime untuk python 2.6, Anda bisa melihatnya

Python-2.6/Modules/datetimemodule.c

Anda juga dapat menemukan versi Mercurial terbaru di web di https://hg.python.org/cpython/file/tip/Modules/_datetimemodule.c

Moe
sumber
Jika Anda mengedit jawaban Anda untuk menunjukkan bahwa datetime .__ file__ menunjuk ke .so di Linux & Mac OS X (meskipun pada Windows objek modul datetime tidak memiliki atribut file ), saya akan menerima jawaban Anda.
Daryl Spitzer
Sebenarnya pada Windows (setidaknya pada versi yang saya gunakan), datetime tidak memiliki atribut file .
Daryl Spitzer
221

Menjalankan python -vdari baris perintah akan memberi tahu Anda apa yang sedang diimpor dan dari mana. Ini berfungsi untuk saya di Windows dan 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
...

Saya tidak yakin apa itu mtime buruk pada instalasi saya!

jblocksom
sumber
8
Keren! Anda juga dapat mengetikkan pernyataan impor spesifik Anda setelah dibuka dalam mode interaktif untuk melihat dari mana lib spesifik berasal.
scorpiodawg
3
Di mana built-inmodul?
loretoparisi
120

Saya menyadari jawaban ini terlambat 4 tahun, tetapi jawaban yang ada menyesatkan orang.

Cara yang tepat untuk melakukan ini adalah tidak pernah __file__, atau mencoba untuk berjalan sys.pathdan mencari sendiri, dll. (Kecuali jika Anda harus kompatibel ke belakang melampaui 2.1).

Ini inspectmodul — khususnya, getfileatau getsourcefile.

Kecuali Anda ingin belajar dan menerapkan aturan-aturan (yang didokumentasikan, tetapi menyakitkan, untuk CPython 2.x, dan tidak didokumentasikan sama sekali untuk implementasi lain, atau 3.x) untuk pemetaan .pycke .pyfile; berurusan dengan arsip .zip, telur, dan paket modul; mencoba berbagai cara untuk mendapatkan jalur ke .so/ .pydfile yang tidak mendukung __file__; mencari tahu apa yang dilakukan Jython / IronPython / PyPy; dll. Dalam hal ini, lakukanlah.

Sementara itu, setiap sumber versi Python dari 2.0+ tersedia online di http://hg.python.org/cpython/file/X.Y/(misalnya, 2.7 atau 3.3 ). Jadi, setelah Anda menemukan itu inspect.getfile(datetime)adalah file .soatau .pydseperti /usr/local/lib/python2.7/lib-dynload/datetime.so, Anda dapat mencarinya di dalam direktori Modul. Tegasnya, tidak ada cara untuk memastikan mana file mendefinisikan modul yang, tapi hampir semua dari mereka adalah baik foo.catau foomodule.c, sehingga seharusnya tidak sulit untuk menebak bahwa datetimemodule.c adalah apa yang Anda inginkan.

abarnert
sumber
3
Mengapa ini __file__tidak berlaku untuk non-builtin? Saya mengerti di mana merangkak sys.path bisa menyakitkan (terutama tanpa mengetahui tentang meta_path), tetapi apakah kekhawatiran Anda tentang penempatan nama antara __file__definisi dan binari?
1
Saya melakukan ini di 2.7.8 pada datetime dan hanya mendapatkan TypeError untuk getfile dan getourcefile. Secara pribadi saya memiliki beberapa versi python diinstal dan saya perlu tahu versi WHICH dari datetimemodule.c itu menunjuk, karena sekarang saya tahu itu tidak menunjuk pada satu itu harus menunjuk pada diberikan versi penerjemah yang berjalan ...
mmitchell
1
@mmitchell: Jika Anda mendapatkan TypeError dari inspect.getfile (datetime), dengan asumsi datetime sebenarnya adalah modul dan bukan sesuatu yang telah Anda tetapkan dengan nama yang sama, saya cukup yakin itu berarti Anda membuat custom build untuk taut secara statis dalam datetime ke juru alih alih-alih menjadikannya modul yang dapat dimuat. Tetapi mungkin ada alasan lain yang belum saya pikirkan. Anda perlu mengajukan pertanyaan baru, dan memberikan lebih banyak info untuk mereproduksi ini.
abarnert
@mmitchell: Sementara itu, tidak ada cara untuk mengetahui versi datetimemodule.c mana yang ditunjuk, karena itu tidak menunjuk pada datetimemodule.c, itu menunjuk pada modul yang dikompilasi yang dibangun dari file C; file C mungkin tidak ada di sistem Anda, mungkin telah diedit sejak Anda mengompilasinya, apa pun.
abarnert
@tristan: Saya tidak yakin saya mengerti apa yang Anda tanyakan, tetapi mungkin ini akan menjawabnya: Setiap kali __file__bekerja, inspect.getfilebekerja; tidak ada situasi di mana menebak apakah menggunakan __file__akan lebih baik daripada hanya menggunakan modul inspeksi.
abarnert
67

The sys.pathdaftar berisi daftar direktori yang akan dicari untuk modul saat runtime:

python -v
>>> import sys
>>> sys.path
['', '/usr/local/lib/python25.zip', '/usr/local/lib/python2.5', ... ]
Greg Hewgill
sumber
10
python -c 'import sys; print "\n".join(sys.path)'akan membiarkan Anda melihatnya tanpa harus jatuh ke dalam python interaktif.
Joe Block
6
Python 3:python -c 'import sys; print("\n".join(sys.path))'
arudzinska
61

Jika Anda menggunakan pip untuk menginstal modul Anda, hanya pip show $modulelokasi yang dikembalikan.

James Mark Mackenzie
sumber
10
(Saya pikir $moduleitu dimaksudkan sebagai variabel pengganti, tidak secara harfiah apa yang akan diketik seseorang. Misalnya, m=numpy; pip show $m... dll, untuk apa pun m)
michael
ini harus ditandai sebagai jawaban paling akurat untuk pertanyaan yang diajukan.
Rahul Goyal
37

dari pustaka standar coba 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))
Diprogram dengan kode
sumber
1
Ini fantastis. Saya apt-get removeDataDog dan masih bisa mengimpornya. Ini membantu saya menemukan di mana file-file itu berada (sehingga saya bisa menghapusnya) ketika solusi lain tidak membantu.
sg
untuk python3.x, imppaket tidak digunakan lagi (sejak versi 3.4) mendukung importlib(sejak 3.1) docs.python.org/3.6/library/imp.html
michael
Sekarang Anda perlu menggunakannya dengan cara ini untuk python3. import importliblaluimportlib.util.find_spec('fontTools')
Medhat
33

datetime adalah modul builtin, jadi tidak ada file sumber (Python).

Untuk modul yang berasal dari .py(atau .pyc) file, Anda dapat menggunakan mymodule.__file__, misalnya

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

Dalam juru bahasa python Anda dapat mengimpor modul tertentu dan kemudian ketik bantuan (modul). Ini memberikan rincian seperti Nama, File, Modul Dokumen, Deskripsi dkk.

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
sumber
Ini memberi saya path lengkap ke file modul sementara jawaban lain hanya memberi path relatif. Terima kasih.
Jerther
12

Berikut ini adalah satu-liner untuk mendapatkan nama file untuk sebuah modul, cocok untuk alias shell:

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

Siapkan sebagai alias:

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

Menggunakan:

$ 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
sumber
9

Lihatlah perintah "cdp" yang bagus ini untuk melakukan cd ke direktori yang berisi sumber untuk modul Python yang ditunjukkan:

cdp () {
  cd "$(python -c "import os.path as _, ${1}; \
    print _.dirname(_.realpath(${1}.__file__[:-1]))"
  )"
}
Daryl Spitzer
sumber
Terima kasih! Itu hanya apa yang saya cari. Cukup aneh mereka tidak akan memasukkan sesuatu semacam itu ke dalam distro python.
Antony Hatchkins
9

Pada windows Anda dapat menemukan lokasi modul python seperti yang ditunjukkan di bawah ini: yaitu menemukan modul rest_framework masukkan deskripsi gambar di sini

Dun0523
sumber
4

Di Ubuntu 12.04, misalnya paket numpy untuk python2, dapat ditemukan di:

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

Tentu saja, ini bukan jawaban umum

nexayq
sumber
0

Tidak semua modul python ditulis dalam python. Datetime kebetulan menjadi salah satu dari mereka yang tidak, dan (di linux) adalah datetime.so.

Anda harus mengunduh kode sumber ke pustaka standar python untuk mendapatkannya.

JimB
sumber
2
Daryl: Anda salah menjawab jawaban Jim, "Datetime kebetulan menjadi salah satu modul python yang tidak ditulis dengan python".
Matthew Trevor
0

Bagi mereka yang lebih suka solusi GUI: jika Anda menggunakan gui seperti Spyder (bagian dari instalasi Anaconda), Anda bisa mengklik kanan nama modul (seperti "csv" di "import csv") dan pilih "go ke definisi "- ini akan membuka file, tetapi juga di atas Anda dapat melihat lokasi file yang tepat (" C: .... csv.py ")

Alona
sumber
0

Jika Anda tidak menggunakan penerjemah maka Anda dapat menjalankan kode di bawah ini:

import site
print (site.getsitepackages())

Keluaran:

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

Elemen kedua di Array akan menjadi lokasi paket Anda. Pada kasus ini:

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

Cara lain untuk memeriksa apakah Anda memiliki beberapa versi python yang diinstal, dari terminal.

-MBP: ~ python3 -m pip tampilkan pyperclip

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

MBP: ~ python -m pip menunjukkan pyperclip

Lokasi: / Pengguna /umeshvuyyuru/Library/Python/2.7/lib/python/site-packages

u_v
sumber
-1

Dalam IDE seperti Spyder, impor modul lalu jalankan modul satu per satu. masukkan deskripsi gambar di sini

Anirudh Sharma
sumber
Mengimpor dan mencetak str()model adalah deskripsi yang lebih akurat tentang apa yang Anda lakukan di tangkapan layar, plus IDE tampaknya tidak relevan untuk solusi ini
mousetail
2
Selamat datang di StackOverflow! Tolong jangan memposting kode menggunakan gambar. Gambar sulit dibaca, tidak dapat dicari, dan tidak dapat dilihat oleh beberapa pembaca. Sebagai gantinya, harap sertakan kode yang relevan secara langsung di badan jawaban Anda.
Brian