Python の sys.path はどこから初期化されるのでしょうか? 質問する

Python の sys.path はどこから初期化されるのでしょうか? 質問する

Python の sys.path はどこから初期化されるのでしょうか?

上院: Python は 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は次のとおりです:

    PYTHONPATH=c:\testdir

PYTHONPATH のパスの前のパスはどこから来るのでしょうか?

ベストアンサー1

編集

私がこれを書いた2015年当時、この件に関する文書は存在しませんでした。今はコメントによると、もしあなたがそれをチェックしたいのであれば。また、散文の説明getpath.pyコード ベースのコメントにあるアルゴリズムについて。私の回答は関連性があり、比較的最新のものであると今でも信じています。

原文は以下

Pythonは本当に賢く設定しようと努力していますsys.pathどのように設定するかは本当に 複雑以下のガイドは、Pythonが何を使用するかを判断する際に何が起こるかを説明する、一般のPythonプログラマー向けの、薄められた、多少不完全で、多少間違っているが、おそらく役に立つガイドです。初期値sys.path、、、およびのsys.executable​​sys.exec_prefixsys.prefix普通Python のインストール。

まず、Python はオペレーティング システムから指示された内容に基づいて、ファイル システム上の実際の物理的な位置をできる限り正確に把握します。OS が単に「python」が実行中であると表示した場合、Python は $PATH で自分自身を見つけます。Python はシンボリック リンクを解決します。この処理が完了すると、Python が見つけた実行可能ファイルのパスが、sys.executable条件なし、論理和なし、またはただしなしの値として使用されます。

sys.exec_prefix次に、およびの初期値を決定しますsys.prefix

pyvenv.cfg同じディレクトリまたは 1 つ上のディレクトリにというファイルがある場合sys.executable、Python はそのファイルを参照します。異なる OS では、このファイルに対して異なる処理が行われます。

Python がこの設定ファイルで探す値の 1 つは、設定オプション です。Python は、後での初期値を動的に設定するときに、home = <DIRECTORY>を含むディレクトリではなく、このディレクトリを使用します。Windows の ファイルに 設定があるが 設定がない場合、 はを含むディレクトリに設定されます。sys.executablesys.prefixapplocal = truepyvenv.cfghome = <DIRECTORY>sys.prefixsys.executable

次に、PYTHONHOME環境変数が調べられます。LinuxとMacでは、環境変数が存在する場合は、sys.prefixおよびsys.exec_prefixが設定されます。PYTHONHOME取って代わるの任意のhome = <DIRECTORY>設定pyvenv.cfg。Windowsでは、環境変数が存在する場合は、sys.prefixおよびsys.exec_prefixが設定されます。PYTHONHOMEない限りに設定home = <DIRECTORY>が存在する場合pyvenv.cfg、代わりにこれが使用されます。

それ以外の場合、これらsys.prefixと は、sys.exec_prefixの場所から逆方向にたどって見つかるsys.executableか、またはhomeによって指定されたディレクトリ(pyvenv.cfg存在する場合)から見つかります。

ファイルがlib/python<version>/dyn-loadディレクトリまたはその親ディレクトリのいずれかで見つかった場合、そのディレクトリはsys.exec_prefixLinux または Mac では に設定されます。 ファイルが ディレクトリまたはそのサブディレクトリのいずれかで見つかった場合、そのディレクトリはLinux、Mac、および Windows では にlib/python<version>/os.py設定され、 は Windowsと同じ値に設定されます。 が設定されている場合、Windows ではこの手順全体がスキップされます。 のディレクトリが使用されるか、 でが設定されている場合はが の初期値として代わりに使用されます。sys.prefixsys.exec_prefixsys.prefixapplocal = truesys.executablehomepyvenv.cfgsys.prefix

これらの「ランドマーク」ファイルが見つからない場合、またはsys.prefixまだ見つかっていない場合、Python は を「フォールバック」値に設定します。たとえば、Linux と Mac では、とsys.prefixの値としてコンパイル済みのデフォルトを使用します。Windows はが完全に解決されるまで待機し、 のフォールバック値を設定します。sys.prefixsys.exec_prefixsys.pathsys.prefix

次に、(皆さんが待ち望んでいたことですが)Python は に含まれる初期値を決定しますsys.path

  1. Python が実行しているスクリプトのディレクトリが に追加されますsys.path。Windows では、これは常に空の文字列であり、代わりにスクリプトが配置されている完全なパスを使用するように Python に指示します。
  2. PYTHONPATH環境変数の内容が設定されている場合はsys.pathない限りWindows を使用しており、applocalが true に設定されていますpyvenv.cfg
  3. <prefix>/lib/python35.zipLinux/Mac およびos.path.join(os.dirname(sys.executable), "python.zip")Windows 上のzip ファイル パスが に追加されますsys.path
  4. Windows で がapplocal = true設定されていない場合pyvenv.cfg、レジストリ キーのサブキーの内容HK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\が追加されます (存在する場合)。
  5. Windowsで がapplocal = true設定されておらずpyvenv.cfg、 がsys.prefix見つからない場合は、コアコンテンツレジストリ キーがHK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\存在する場合は、それが追加されます。
  6. Windows で がapplocal = true設定されていない場合pyvenv.cfg、レジストリ キーのサブキーの内容HK_LOCAL_MACHINE\Software\Python\PythonCore\<DLLVersion>\PythonPath\が追加されます (存在する場合)。
  7. Windowsで がapplocal = true設定されておらずpyvenv.cfg、 がsys.prefix見つからない場合は、コアコンテンツレジストリ キーがHK_CURRENT_USER\Software\Python\PythonCore\<DLLVersion>\PythonPath\存在する場合は、それが追加されます。
  8. Windows で、PYTHONPATH が設定されておらず、プレフィックスが見つからず、レジストリ キーも存在しない場合は、PYTHONPATH の相対コンパイル時値が追加されます。それ以外の場合、この手順は無視されます。
  9. コンパイル時マクロ PYTHONPATH 内のパスは、動的に見つかった を基準として追加されますsys.prefix
  10. Mac および Linux では、 の値sys.exec_prefixが追加されます。Windows では、 を動的に検索するために使用された (または使用されるはずだった) ディレクトリがsys.prefix追加されます。

Windowsのこの段階でプレフィックスが見つからなかった場合、Pythonは検索してプレフィックスを決定しようとします。全てsys.path何かが見つかるまで、以前のディレクトリと同様に、ランドマーク ファイル用のディレクトリを検索しますsys.executable。見つからない場合は、sys.prefix空白のままになります。

最後に、このすべての後、Python はsiteモジュールをロードし、さらに次のものを追加しますsys.path

まず、ヘッドとテール部分から最大 4 つのディレクトリを構築します。ヘッド部分には、sys.prefixand を使用しますsys.exec_prefix。空のヘッドはスキップされます。テール部分には、空の文字列 and then lib/site-packages(Windows の場合) またはlib/pythonX.Y/site-packagesand then lib/site-python(Unix および Macintosh の場合) を使用します。異なるヘッドとテールの組み合わせごとに、既存のディレクトリを参照しているかどうかを確認し、参照している場合は sys.path に追加し、新しく追加されたパスで構成ファイルも検査します。


編集: もうありませんgetpathp.c(冒頭のリンク複雑単語)以来2021年12月実装が Python に移植されたため:getpath.py

おすすめ記事