2017-04-16 11 views
2

この質問は、Python 2.7と相対インポートのコンテキストにあります。私は関連する質問をしてきましたが、まだ私のために働いていないことがあります。私はここに何が欠けているのか分かりません。続き兄弟ディレクトリからのインポートでの問題

は私のディレクトリ階層

. 
|-> wrapper.py 
|-> __init__.py 
|-> util 
| |-> hello.py 
| |-> __init__.py 
|-> src 
| |-> wrapper.py 
| |-> __init__.py 

あるすべての__init__.py空白のファイルが唯一./util/hello.py読み取り方法です後

「を含むパッケージなどのディレクトリを扱う」にあり。これは独自の主な機能を持ち、独自の機能を実行できます。

以下は、どのように./wrapper.pyが読み込まれるかです。これには独自の主な機能があり、目的を達成するために./util/hello.pyを使用します。

#!/usr/bin/python 
# This is wrapper.py. 

import sys 
from util import hello 

# Define a main() function that prints a little greeting. 
def main(): 
    hello.main()  # This prints "Hello World!!!" 

# Standard boilerplate that calls the main() function. 
if __name__ == '__main__': 
    main() 

以下は、どのように./src/wrapper.pyが読み込まれるかです。

#!/usr/bin/python 
# This is wrapper.py. 

import sys 
from ..util import hello 

# Define a main() function that prints a little greeting. 
def main(): 
    hello.main()  # This prints "Hello World!!!" 

# Standard boilerplate that calls the main() function. 
if __name__ == '__main__': 
    main() 

ご覧のとおり、これは最小限の変更で./wrapper.pyをコピーしたものです(インポートの変更)。すべて__init__.pyも存在します。しかし、それを実行しようとすると次のエラーが発生します。私は、次のようhello.pyをインポートする場合

Traceback (most recent call last): 
    File "wrapper.py", line 8, in <module> 
    from ..util import hello 
ValueError: Attempted relative import in non-package 

しかし、それは動作します:

import os 
sys.path.append(os.path.abspath("../util/")) 
import hello 

二つの質問:

Q1を。何が間違っているのか、私の注意を逃しているのですか?

Q2。どうすれば./src/__init__.pyをコーディングすれば、 "import hello"だけが./src/wrapper.pyで動作するようにできますか?

+0

を使用することができますか?関連 - https://stackoverflow.com/questions/11536764/how-to-fix-attempted-relative-import-in-non-package-even-with-init-py –

+0

Q1に対処する多くの既存の回答があります「非パッケージで相対インポートを試みました」を検索します。私は質問が間違った方向につながるので、Q2に答えることはできません。あなたは 'python -m src.wrapper'を走らせることができます。' import hello'は 'from hello import hello'も' src/wrapper.py'で動作します。私は一般的にトップレベル以外の場所からの相対輸入を避けることが賢明だと思います! – mhoff

+0

@AshishNitinPatil: "./src"を "python wrapper.py"として実行しています。 –

答えて

1

単純な答えは、すべてのコードに対して親パッケージを用意する必要があるということです。 __init__.pyをルートディレクトリに置くだけでパッケージとして動作するとは限りません。

私が悪いから始まり、善と悪にあなたのオプションを分割します:

が悪い - 相対的な輸入:あなたは何をすべき がパッケージに(別名.)すべてあなたのコードを入れています(srcはパッケージbtwの悪い名前です)。と言ってくださいmypackage。次にsrc.wrappermypackage.src.wrapperとしてインポートすることができます。その場所は、にあるPythonインタプリタのように、mypackageが含まれています。パッケージをインストールすると、パス上で利用できるようになります。相対的な輸入となぜ彼らが悪いの詳細については

グッド

- 非相対輸入: より良いアプローチはを通じて輸入されパッケージを絶対的な方法で使用します。親パッケージmypackageをまだ作成する必要がありますが、今度は相対インポートを取り除き、からimport mypackage.util.hellowrapper.pyに書き込んでください。これを行うには、mypackageを含むディレクトリを含めるようにpythonパスを設定する必要があります。

これを行うには、setup.pyファイルを作成し、パッケージをインストールすることをお勧めします。開発のためには、Pythonのパッケージにpython setup.py developまたはpip install -e .

詳細を使用する必要があります:https://packaging.python.org/distributing/

編集:あなたのQ2のため 、あなたは絶対的な輸入品を使用する場合はimport mypackage.util.hello as hellofrom mypackage.util import helloを使用することができます。どちらも同じです。

いくつかの特殊なケースでは、/mypackage/__init__.py内部import util.hello as helloを書くことに興味がある可能性があり、その後、あなたはどのように `。/ wrapper.py`を実行しているfrom mypackage import helloなど

関連する問題