Dari mana sys.path Python diinisialisasi?

111

Dari mana sys.path Python diinisialisasi?

UPD : Python menambahkan beberapa jalur sebelum merujuk ke PYTHONPATH:

    >>> import sys
    >>> from pprint import pprint as p
    >>> p(sys.path)
    ['',
     'C:\\Python25\\lib\\site-packages\\setuptools-0.6c9-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\orbited-0.7.8-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\morbid-0.8.6.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\demjson-1.4-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\stomper-0.2.2-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\uuid-1.30-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\stompservice-0.1.0-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\cherrypy-3.0.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\pyorbited-0.2.2-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\flup-1.0.1-py2.5.egg',
     'C:\\Python25\\lib\\site-packages\\wsgilog-0.1-py2.5.egg',
     'c:\\testdir',
     'C:\\Windows\\system32\\python25.zip',
     'C:\\Python25\\DLLs',
     'C:\\Python25\\lib',
     'C:\\Python25\\lib\\plat-win',
     'C:\\Python25\\lib\\lib-tk',
     'C:\\Python25',
     'C:\\Python25\\lib\\site-packages',
     'C:\\Python25\\lib\\site-packages\\PIL',
     'C:\\Python25\\lib\\site-packages\\win32',
     'C:\\Python25\\lib\\site-packages\\win32\\lib',
     'C:\\Python25\\lib\\site-packages\\Pythonwin']

PYTHONPATH saya adalah:

    PYTHONPATH=c:\testdir

Saya ingin tahu dari mana asal jalur sebelum jalur PYTHONPATH?

Alex
sumber

Jawaban:

77

Python benar-benar berusaha keras untuk mengatur dengan cerdas sys.path. Bagaimana ini diatur bisa menjadi sangat rumit . Panduan berikut adalah, agak-tidak lengkap, agak-salah, tapi mudah-mudahan-berguna panduan encer untuk peringkat-dan-file python programmer dari apa yang terjadi ketika tokoh python tahu apa yang harus digunakan sebagai nilai awal dari sys.path, sys.executable, sys.exec_prefix, dan sys.prefixpada instalasi python normal .

Pertama, python melakukan level terbaiknya untuk mengetahui lokasi fisik sebenarnya pada sistem file berdasarkan apa yang diberitahukan oleh sistem operasi. Jika OS hanya mengatakan "python" sedang berjalan, ia menemukan dirinya di $ PATH. Ini menyelesaikan tautan simbolis apa pun. Setelah melakukan ini, jalur eksekusi yang ditemukannya digunakan sebagai nilai untuk sys.executable, no ifs, ands, or buts.

Selanjutnya, ini menentukan nilai awal untuk sys.exec_prefixdan sys.prefix.

Jika ada file yang dipanggil pyvenv.cfgdi direktori yang sama dengan sys.executableatau satu direktori ke atas, python akan melihatnya. OS yang berbeda melakukan hal yang berbeda dengan file ini.

Salah satu nilai dalam file konfigurasi yang dicari python adalah opsi konfigurasi home = <DIRECTORY>. Python akan menggunakan direktori ini dan bukan direktori yang berisi sys.executable ketika ia secara dinamis menetapkan nilai awal sys.prefixnanti. Jika applocal = truepengaturan muncul di pyvenv.cfgfile pada Windows, tetapi tidak home = <DIRECTORY>pengaturan, maka sys.prefixakan diatur ke direktori yang berisi sys.executable.

Selanjutnya, PYTHONHOMEvariabel lingkungan diperiksa. Di Linux dan Mac, sys.prefixdan sys.exec_prefixdisetel ke PYTHONHOMEvariabel lingkungan, jika ada, menggantikanhome = <DIRECTORY> setelan apa pun di pyvenv.cfg. Di Windows, sys.prefixdan sys.exec_prefixdiatur ke PYTHONHOMEvariabel lingkungan, jika ada, kecuali ada home = <DIRECTORY>pengaturan pyvenv.cfg, yang digunakan sebagai gantinya.

Jika tidak, ini sys.prefixdan sys.exec_prefixditemukan dengan berjalan mundur dari lokasi sys.executable, atau homedirektori yang diberikan oleh pyvenv.cfgjika ada.

Jika file lib/python<version>/dyn-loadditemukan di direktori itu atau salah satu direktori induknya, direktori itu disetel ke sys.exec_prefixLinux atau Mac. Jika file lib/python<version>/os.pyditemukan di direktori atau subdirektorinya, direktori tersebut disetel ke sys.prefixLinux, Mac, dan Windows, dengan sys.exec_prefixnilai yang sama seperti sys.prefixdi Windows. Seluruh langkah ini dilewati di Windows jika applocal = truedisetel. Entah direktori sys.executableyang digunakan atau, jika homedisetel pyvenv.cfg, yang digunakan sebagai gantinya untuk nilai awal sys.prefix.

Jika tidak dapat menemukan file "tengara" ini atau sys.prefixbelum ditemukan, maka python disetel sys.prefixke nilai "fallback". Linux dan Mac, misalnya, menggunakan default yang telah dikompilasi sebelumnya sebagai nilai dari sys.prefixdan sys.exec_prefix. Windows menunggu hingga sys.pathbenar-benar diketahui untuk menetapkan nilai fallback sys.prefix.

Kemudian, (apa yang Anda semua tunggu-tunggu,) python menentukan nilai awal yang akan dimasukkan sys.path.

  1. Direktori skrip yang sedang dieksekusi python ditambahkan sys.path. Di Windows, ini selalu berupa string kosong, yang memberi tahu python untuk menggunakan jalur lengkap tempat skrip berada.
  2. Konten variabel lingkungan PYTHONPATH, jika disetel, ditambahkan ke sys.path, kecuali Anda menggunakan Windows dan applocaldisetel ke true di pyvenv.cfg.
  3. Jalur file zip, yang ada <prefix>/lib/python35.zipdi Linux / Mac dan os.path.join(os.dirname(sys.executable), "python.zip")di Windows, ditambahkan ke sys.path.
  4. Jika di Windows dan tidak ada applocal = trueyang disetel pyvenv.cfg, konten subkunci dari kunci registri HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\akan ditambahkan, jika ada.
  5. Jika di Windows dan tidak ada applocal = trueyang ditetapkan pyvenv.cfg, dan sys.prefixtidak dapat ditemukan, maka konten inti dari kunci registri HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\akan ditambahkan, jika ada;
  6. Jika di Windows dan tidak ada applocal = trueyang disetel pyvenv.cfg, konten subkunci dari kunci registri HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\akan ditambahkan, jika ada.
  7. Jika di Windows dan tidak ada applocal = trueyang ditetapkan pyvenv.cfg, dan sys.prefixtidak dapat ditemukan, maka konten inti dari kunci registri HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\akan ditambahkan, jika ada;
  8. Jika di Windows, dan PYTHONPATH tidak disetel, awalan tidak ditemukan, dan tidak ada kunci registri yang ada, maka nilai waktu kompilasi relatif PYTHONPATH akan ditambahkan; jika tidak, langkah ini akan diabaikan.
  9. Jalur di makro waktu kompilasi PYTHONPATH ditambahkan relatif ke yang ditemukan secara dinamis sys.prefix.
  10. Di Mac dan Linux, nilai sys.exec_prefixditambahkan. Pada Windows, direktori yang digunakan (atau akan digunakan) untuk mencari secara dinamis sys.prefixditambahkan.

Pada tahap ini di Windows, jika tidak ada prefiks yang ditemukan, maka python akan mencoba menentukannya dengan mencari semua direktori di sys.pathuntuk file landmark, seperti yang coba dilakukan dengan direktori sys.executablesebelumnya, hingga menemukan sesuatu. Jika tidak, sys.prefixdikosongkan.

Akhirnya, setelah semua ini, Python memuat sitemodul, yang menambahkan hal-hal lebih jauh ke sys.path:

Ini dimulai dengan membangun hingga empat direktori dari bagian head dan tail. Untuk bagian kepala menggunakan sys.prefixdan sys.exec_prefix; kepala kosong dilewati. Untuk bagian ekor, menggunakan string kosong lalu lib/site-packages(di Windows) atau lib/pythonX.Y/site-packages kemudian lib/site-python(di Unix dan Macintosh). Untuk setiap kombinasi head-tail yang berbeda, ia melihat apakah itu merujuk ke direktori yang ada, dan jika demikian, menambahkannya ke sys.path dan juga memeriksa jalur yang baru ditambahkan untuk file konfigurasi.

djhaskin987
sumber
1
Terlepas dari apa yang dikatakan oleh dokumennya, sys.executablebisa berupa symlink atau sebenarnya bisa apa saja jika argv[0]mengandung garis miring. Sebenarnya jalan ke executable (dari execv(path, argv)panggilan) tidak digunakan.
jfs
1
Mengenai poin pertama Anda untuk sys.pathdi windows 10: Saya selalu mendapatkan path lengkap dari dir skrip saya sebagai sys.path [0] (bukan cwd ''). Anda harus dapat menjalankan sesuatu sepertipython some\other\path\than\cwd\main.py
ford04
Saya setuju dengan @ ford04. Poin 1 tidak benar: Di Windows, direktori skrip ditambahkan ke sys.path, bukan jalur kosong, atau cwd. Ini ada dalam berbagai pemasangan Python 3.x.
gwideman
1
Wow, ini luar biasa! Saya melihat sekitar 10 pertanyaan dan jawaban lain sebelum menemukan ini, "kebenaran", meskipun Anda dengan rendah hati mengakui bahwa Anda tidak memiliki semuanya.
Mike Williamson
1
Saya akan menambahkan bahwa file yang relevan di site-packagesmemiliki .pthdan .egg-linkakhiran.
florisla