Pythonでモジュールをインポートするのは複雑なので、それをクリアするために実験を行っています。ファイル構造は次のとおりです。
PythonTest/
package/
__init__.py
test.py
の内容 __init__.py
:
package = 'Variable package in __init__.py'
from package import test
の内容 test.py
:
from package import package
print package
package
(in PythonTest
)から離れてpython package/test.py
、私は得ます:
Traceback (most recent call last):
File "package/test.py", line 1, in <module>
from package import package
ImportError: No module named package
予想される出力はVariable package in __init__.py
。私は何が間違っているのですか?
ただし、インタラクティブモードで期待される出力を得ることができます。
sunqingyaos-MacBook-Air:PythonTest sunqingyao$ python
Python 2.7.10 (default, Oct 23 2015, 19:19:21)
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.59.5)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import package
Package in __init__.py
まず、Pythonパッケージとモジュールを検索する方法を見てみましょう。 sys.path
モジュールの検索パスを指定する文字列のリスト。環境変数
PYTHONPATH
から初期化され、さらにインストールに依存するデフォルト。
それが検索パスです。したがって、モジュール/パッケージがsys.path
のいずれかにある場合、pythonインタープリターはそれを見つけてインポートできます。ドキュメントには次のように書かれています:
プログラムの起動時に初期化されると、このリストの最初の項目
path[0]
は、Pythonインタープリターを呼び出すために使用されたスクリプトを含むディレクトリです。スクリプトディレクトリが利用できない場合(たとえば、インタプリタがインタラクティブに呼び出される場合、またはスクリプトが標準入力から読み取られる場合)、path[0]
は空の文字列であり、Pythonが最初に現在のディレクトリ内のモジュールを検索するように指示します。
例としてtest.py
を変更しました。
import sys; import pprint
pprint.pprint(sys.path)
from package import package
print package
2つのケースがあります:
$ python package/test.py
['/Users/laike9m/Dev/Python/TestPython/package',
'/usr/local/lib/python2.7/site-packages/doc2dash-2.1.0.dev0-py2.7.Egg',
'/usr/local/lib/python2.7/site-packages/zope.interface-4.1.3-py2.7-macosx-10.10-x86_64.Egg',
'/usr/local/lib/python2.7/site-packages/six-1.10.0-py2.7.Egg',
'/usr/local/lib/python2.7/site-packages/colorama-0.3.3-py2.7.Egg',
ご覧のとおり、path[0]
は/Users/laike9m/Dev/Python/TestPython/package
です。これは、Pythonインタープリターを呼び出すために使用されたスクリプトtest.py
を含むディレクトリです。
$ python
Python 2.7.12 (default, Jun 29 2016, 14:05:02)
[GCC 4.2.1 Compatible Apple LLVM 7.3.0 (clang-703.0.31)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import package
['',
'/usr/local/lib/python2.7/site-packages/doc2dash-2.1.0.dev0-py2.7.Egg',
'/usr/local/lib/python2.7/site-packages/zope.interface-4.1.3-py2.7-macosx-10.10-x86_64.Egg',
'/usr/local/lib/python2.7/site-packages/six-1.10.0-py2.7.Egg',
'/usr/local/lib/python2.7/site-packages/colorama-0.3.3-py2.7.Egg',
...
2番目のケースは、インタラクティブに呼び出された場合、「path[0]
は空の文字列であり、Pythonが最初に現在のディレクトリ内のモジュールを検索するように指示します。」現在のディレクトリは何ですか?/Users/laike9m/Dev/Python/TestPython/
。(これは私のマシンのパスです。あなたの場合はPythonTest
へのパスと同じです)
今、あなたは答えを知っています:
なぜpython package/test.py
はImportError: No module named package
を与えたのですか?
通訳はパッケージを「見ない」からです。インタプリタがパッケージpackage
を認識するためには、PythonTest
がsys.path
にある必要がありますが、そうではありません。
なぜこれがインタラクティブモードで機能したのですか?
現在、PythonTest
はsys.path
にあるため、インタプリタはパッケージpackage
を見つけることができます。