2016-10-06 7 views
2

この構造は一例複数の相対輸入は3.5

pkg\ 
    test\ 
    __init__.py 
    test.py 
    __init__.py 
    source.py 
    another_source.py 

another_source.py

class Bar(): 
    def __init__(self): 
    self.name = "bar" 

source.py

from another_source import Bar 
class Foo(): 
    def __init__(self): 
    self.name = "foo" 
    b = Bar() 

test.py

from ..source import Foo 

if __name__== "__main__": 
    f = Foo() 
    print(f.name) 
あります

これでtest.pyを実行します。それは私が私の現在のパッケージの上に行くと

python -m pkg.test.test 

を実行します。しかし、これは動作しませんし、私はすべてのanother_sourceを削除した場合のpythonは私にトレースバック

Traceback (most recent call last): 
    File "-\Python35\lib\runpy.py", line 170, in _run_module_as_main 
    "__main__", mod_spec) 
    File "-\Python35\lib\runpy.py", line 85, in _run_code 
    exec(code, run_globals) 
    File "~\test\test.py", line 1, in <module> 
    from ..source import Foo 
    File "~\source.py", line 1, in <module> 
    from another_source import Bar 
ImportError: No module named 'another_source' 

を与えるために持っているanswerとして受け入れられてきたように それはうまくいくが、それは解決策ではない。

私の上の1つのディレクトリである場所からクラスをインポートするには、ここまできれいな方法がありますか?

+1

'from pkg.source import Foo'を修正する必要があります。 –

答えて

1

pkg.sourceは、pkg.another_sourceモジュールからトップレベルのものをインポートしようとしています。そのインポートを修正する必要があります。正しく覚えていれば、

from .another_source import Bar 
# or 
from pkg.another_source import another_source 
+0

しかし、私のメインスクリプトのインポート(source.pyと同じディレクトリ)は失敗します。 – Nozdrum

+0

@Nozdrum:そうすれば、これらのプログラムを実行したときにパッケージの階層がどこから始まるのかは、おそらく一貫していません。それらを 'pkg'ディレクトリの上から' python -m pkg.whatever'として実行する必要があります。または、ここで説明するにはあまりにも多くの '__package__'と' sys.path'を修正するための少しの定型文を入れる必要があります(ただし、[PEP 366](https://www.python.org/dev/peps/pep-0366/)を読むと良いスタートになるでしょう)。 – user2357112

+0

test.pyを実行するのと同じ方法でmain.pyを実行すると動作します。しかし、なぜそれが機能するかについては、私には本当に意味をなさない。 -mスイッチは「ライブラリモジュールをスクリプトとして実行する」と言っていますが、ライブラリモジュールは実行していません。私は "main"スクリプトを実行しています。私のtest.pyはライブラリではなく、テストケースです。 – Nozdrum