私は最近python ImportErrorの問題を抱えていました。ローカルコンピューターで実行しているときにモジュールが見つかりましたが、CIサーバーでは見つかりませんでした。この問題は、スクリプトのsys.path.append(path)
をsys.path.insert(0, path)
と交換することで解決しました。ここで、path
は文字列モジュールの場所です。
これは私のモジュールであり、インストールされたパッケージではないため( 関連する質問 )、なぜパスの順序がこの問題を修正するのですか?
pythonは、sys.path
リストの最初のディレクトリから順番にディレクトリをチェックインするため、探していた.py
ファイルが見つかるまで。
理想的には、現在のディレクトリまたはスクリプトのディレクトリは、変更した場合を除き、リストの最初の要素であり常に最初の要素です。 ドキュメント から-
プログラムの起動時に初期化されると、このリストの最初の項目であるpath [0]は、Pythonインタープリターの呼び出しに使用されたスクリプトを含むディレクトリです。スクリプトディレクトリが利用できない場合(たとえば、インタープリターが対話的に呼び出される場合、またはスクリプトが標準入力から読み取られる場合)、path [0]は空の文字列であり、Pythonに現在のモジュールを検索します最初にディレクトリ。 PYTHONPATHの結果としてエントリが挿入される前に、スクリプトディレクトリが挿入されることに注意してください。
したがって、おそらく、現在のディレクトリ(スクリプトの実行元)に、インポート元のモジュールと同じ名前の.py
ファイルがありました。
また、ImportError
sについて注意することは、インポートエラーが言うことを言うことができます-ImportError: No module named main
-それはmain.py
が上書きされることを意味しません読み込もうとする問題。この上のいくつかのモジュールは、.py
または他のファイルで上書きされました。
例-
私のディレクトリ構造は次のようになります-
- test
- shared
- __init__.py
- phtest.py
- testmain.py
今testmain.py
から、from shared import phtest
を呼び出して、正常に動作します。
test
ディレクトリ `にshared.pyを導入したとしましょう。例-
- test
- shared
- __init__.py
- phtest.py
- testmain.py
- shared.py
from shared import phtest
からtestmain.py
を実行しようとすると、エラーが発生します-
ImportError: cannot import name 'phtest'
上記のように、問題の原因となっているファイルはshared.py
ではなくphtest.py
です。
私はPythonの初心者です。Anandの答えは非常に良いが、私には非常に複雑であることがわかりました。
1)insert
およびappend
メソッドはsys.path
に固有ではなく、他の言語と同様に、リストまたは配列にアイテムを追加します。
* append(item)
は、リストの最後にitem
を追加します。
* insert(n, item)
は、リストのn番目の位置にitem
を挿入します(先頭に0
、最初の要素の後に1
など)。
2)アナンドが言ったように、pythonはパスの各ディレクトリにあるインポートファイルをパスの順に検索します。
*ファイル名の衝突がない場合、パスの順序は影響しません。
*パスで既に定義されている関数を処理し、append
を使用してパスを追加する場合、関数ではなく定義済みの関数を取得します。
しかし、append
ではなくinsert
を使用して、Pythonの標準動作をオーバーロードしないようにし、ファイルとメソッドにあいまいでない名前を使用する方が良いと思います。