2017-10-07 5 views
-1

私は、他のソースファイルをインポートするのと同じように、Pythonのような頭痛を引き起こすことはありません。だからここに質問があります: 私のモジュールのインポートは、コードの実行方法に依存する必要がありますか?Pythonモジュールのインポートは、コードの実行方法によって異なりますか?

私は、次のディレクトリ構造を持っている:

./__init__.py 
./config.py 
./kmer 
./kmer/__init__.py 
./kmer/__main__.py 
./kmer/__pycache__ 
./kmer/__pycache__/__init__.cpython-36.pyc 
./kmer/__pycache__/__main__.cpython-36.pyc 
./kmer/__pycache__/bed.cpython-36.pyc 
./kmer/__pycache__/config.cpython-36.pyc 
./kmer/__pycache__/reference.cpython-36.pyc 
./kmer/__pycache__/sets.cpython-36.pyc 
./kmer/bed.py 
./kmer/config.py 
./kmer/reference.py 
./kmer/sets.py 

私はkmerパッケージ内の他のモジュールからkhmer内のモジュールをインポートしたいです。シンプル?

だから私はbed.pyのでこれを追加します。

import reference 
import config 
import sets 

私はkmerディレクトリからpython bed.pyを実行すると今のものはうまく動作します。 1つのディレクトリに戻ってpython kmer/bed.pyに電話しても問題ありません。 pythonのように、指定されたファイルを基準にしてインポートされたモジュールを検索します。

kmerディレクトリのpython -m bedディレクトリを再度実行すると、正常に動作しますが、1つのディレクトリに戻ってを実行すると、モジュールエラーが発生します。ここでは、Pythonはインタプリタのカレントディレクトリ内のモジュールを探します。このディレクトリはファイルシステム上のどこにでも置くことができるので、相対的なインポートは機能しません。

これは、基本的には、コードがどのように実行されるかに依存してインポートが意味をなさないことを意味します。私はこれがどのように動作するはずであるかについての説明に感謝します。

this質問に対する回答を含めてかなり多くのリソースを見てきましたが、非常に詳細ですが(私が実際に見つけた最良の説明の1つですが)問題を解決していないし、 。

更新:この質問は、相対インポートのさまざまな側面、より正確には、コードを実行するさまざまな方法が、重複としてマークされているものよりインポートにどのように影響するかに焦点を当てていると思います。それで私は最初に他の質問を述べました。したがって、私はこれが重複しているとは思わない。

+0

あなたの問題を解決するように見えるので、リンクされた質問があなたの問題を解決しない方法を説明する必要があります。 – user2357112

+0

@ user2357112この質問を異なるものにするのは、以下のDavisの答えが指摘する、パッケージとスクリプトのセマンティクスの混在部分です。私はリンクされた質問から理解を得ていませんでしたし、理解は当然、主観的です。 – DarthPaghius

答えて

1

パッケージを書くときは、それをパッケージとして常に扱う必要があります。まず、パッケージ内の相対インポートを使用することを意味します。from . import referencebed.pyに書き込みます。

またそれにアクセスする方法のための答えはいつも同じであることを意味する:(通常PYTHONPATH経由)sys.pathkmerを含むディレクトリを置きます。たとえのモジュールをスクリプトとして実行していても、それはである必要があります。

残念ながら、それはスクリプトとしてパッケージ内のモジュールを実行するために、悪い考えです:モジュールのファイルがまだその適切な名前で再びをインポートの対象である(というよりも__main__は、最初の時間を使用しました)。唯一の堅牢な唯一の解決策は、__main__.pyと書いてパッケージをスクリプトとして実行し、パブリックモジュール名のオーバーロードを避けることです。

最後に、スクリプトのディレクトリをsys.pathに置くPythonの「機能」にはほとんど注意を払わないでください。 sys.pathで便利なディレクトリを持つスクリプトは、必ずしもモジュールであるため(名前を識別子にしないなどのトリックの場合を除く)、名前の衝突を気にしない玩具の問題以外は役に立ちません。さらに、他の場所にインストールされたスクリプトでライブラリを利用できるようにするには、とにかくsys.pathにアクセスする必要があります。

+0

'-m'フラグでパッケージ内のモジュールの1つを実行しようとしても、' SystemError:Parent module '' not loaded'エラーが表示されます。あなたの言ったことと矛盾していませんか? – DarthPaghius

+0

@Parsoa:どのコマンドラインを使用しましたか?それは完全な例外メッセージですか? –

関連する問題