Python 3 の相対インポートについては既にかなりの数の質問があるようですが、それらの多くを調べても、私の問題に対する答えはまだ見つかりませんでした。そこで、質問します。
下記のようなパッケージがあります
package/
__init__.py
A/
__init__.py
foo.py
test_A/
__init__.py
test.py
test.py には次の 1 行があります:
from ..A import foo
今、私は のフォルダにいてpackage
、実行します
python -m test_A.test
メッセージを受け取りました
"ValueError: attempted relative import beyond top-level package"
しかし、たとえば の親フォルダーにいる場合はpackage
、次を実行します。
cd ..
python -m package.test_A.test
すべて順調。
ここで質問です。のフォルダ内にいるときにpackage
、test_A サブパッケージ内のモジュールを として実行するとtest_A.test
、私の理解では、..A
は 1 レベルだけ上がり、そのレベルもまだpackage
フォルダ内にあるのに、なぜ というメッセージが表示されるのでしょうかbeyond top-level package
。このエラー メッセージが表示される原因は何でしょうか。
ベストアンサー1
編集: この質問に対するより良い/より一貫した回答は他の質問にあります:
なぜ動作しないのでしょうか? Python はパッケージがどこからロードされたかを記録しないからです。 そのため、 を実行するとpython -m test_A.test
、基本的にtest_A.test
実際に に格納されている情報が破棄されるだけですpackage
(つまり、 はpackage
パッケージとは見なされません)。 を試行すると、from ..A import foo
もう存在しない情報 (つまり、ロードされた場所の兄弟ディレクトリ) にアクセスしようとします。 概念的には、from ..os import path
にファイルを許可することに似ています。 パッケージを区別する必要があるため、これは良くありません。 別のパッケージから何かを使用する必要がある場合は、 を使用してグローバルに参照し、とを使用して Python にそれがどこにあるか判断させるmath
必要があります。from os import path
$PATH
$PYTHONPATH
を使用する場合python -m package.test_A.test
、を使用すると、何が入っているかが追跡され、読み込まれた場所の子ディレクトリにアクセスしているだけなので、を使用するとfrom ..A import foo
問題なく解決されます。package
Python はなぜ現在の作業ディレクトリをパッケージと見なさないのでしょうか? 全く分かりませんが、とても便利だと思います。