2016-08-18 11 views
0

この質問は多くの時間を要請されましたが、解決策のどれも私の場合は役に立たないようです。私はこのPython3のインポートに問題がある

my_project/ 
    main.py 
    bootstrap/ 
     __init__.py 
     boot.py 
    consumer/ 
     __init__.py 
     main.py 

のようなディレクトリ構造は、トップレベルのディレクトリ(myproject)にいるとpython3 consumer/main.pyを実行する必要があり

でエラーが発生します:

Traceback (most recent call last): 
    File "consumer/main.py", line 7, in <module> 
    from bootstrap.boot import MyClass 
ImportError: No module named 'bootstrap' 

奇妙なことは、そのモジュールをインポートすると、インタプリタを使用していることです期待どおりに動作します。 PyCharmからコードを実行するとうまくいきます。

「フルパス」でインポートしようとしました。同じImportErrorで失敗するfrom my_project.bootstrap.boot import MyClassです。私はまた、相対輸入を試してみました。また、これを修正SystemError: Parent module '' not loaded, cannot perform relative import

一つのハックで失敗しましたfrom .bootstrap.boot import MyClassは、その両親、私はvirtualenvのactivateスクリプト

+0

"my_project.bootstrap import MyClass"を試しましたか? – danielfranca

+0

はい、質問を編集しました。ありがとうございます。 – ivica

+1

'__init __。py'を' my_project/'ディレクトリに追加しようとしたら、それが – dhdavvie

答えて

4

モジュール検索パスは、現在のディレクトリが含まれているため、あなたはこのエラーを取得しているの下部にexport PYTHONPATH="/root/my_project"を追加したときではなく、 ;あなたの他のモジュールはPYTHONPATHにないので、インポートすることはできません。

スクリプト内にsys.pathを印刷して、これを見つけることができます。

私は、次のディレクトリtを作成しました:ここ

$ tree 
. 
├── a.py 
├── bar 
│   ├── __init__.py 
│   └── world.py 
└── foo 
    ├── hello.py 
    └── __init__.py 

2 directories, 5 files 

hello.pyの源である:

$ cat foo/hello.py 
import sys 
print("I am in {}".format(__file__)) 
for path in sys.path: 
    print(path) 

from bar.world import var 
print(var) 

私はfoo/hello.pyを実行し、bar/world.pyから何かをインポートしようとすると、今、何が起こるか見て;

$ python foo/hello.py 
I am in foo/hello.py 
/home/burhan/t/foo 
/usr/lib/python2.7 
/usr/lib/python2.7/plat-x86_64-linux-gnu 
/usr/lib/python2.7/lib-tk 
/usr/lib/python2.7/lib-old 
/usr/lib/python2.7/lib-dynload 
/home/burhan/.local/lib/python2.7/site-packages 
/usr/local/lib/python2.7/dist-packages 
/usr/lib/python2.7/dist-packages 
Traceback (most recent call last): 
    File "foo/hello.py", line 6, in <module> 
    from bar.world import var 
ImportError: No module named bar.world 

印刷されたパスからは、システム全体のPythonライブラリパスとスクリプトの現在のディレクトリのみが表示されます。このため、bar.worldが見つかりません。

この問題を解決するには、PYTHONPATHを調整するか相対インポートを使用できます。例えば:

$ PYTHONPATH=../t python foo/hello.py 
I am in foo/hello.py 
/home/burhan/t/foo 
/home/burhan/t 
/usr/lib/python2.7 
/usr/lib/python2.7/plat-x86_64-linux-gnu 
/usr/lib/python2.7/lib-tk 
/usr/lib/python2.7/lib-old 
/usr/lib/python2.7/lib-dynload 
/home/burhan/.local/lib/python2.7/site-packages 
/usr/local/lib/python2.7/dist-packages 
/usr/lib/python2.7/dist-packages 
42 

あなたは私が手動でPYTHONTPATHをオーバーライドし、(42はバー/世界から来ている)スクリプトの共通の親を追加していここに気づきます。

相対インポートを使用してこれを修正するには、最初に最上位ディレクトリにパッケージを作成する必要があります。それ以外の場合は有名なAttempted relative import in non-packageエラーが発生します。これとPython 3のインポートの仕組みの詳細については、次をご覧ください:Relative imports in Python 3

+1

のトップレベルをパッケージとして作成するのを手伝ってもらえますか? – dhdavvie

関連する問題