6

Python で相対インポートを行う方法がわかりません。私は現在、最初の主要なプロジェクトに取り組んでいるので、単体テストを使用して正しく実行したいと考えています。ただし、ファイル構造と相対インポートに問題があります。

これが私の現在の構造です:

App/
  __init__.py
  src/
    __init__.py
    person.py
  tests/
    __init__.py
    person_tests.py

私がやりたいことは、単体テストのために person.py を person_tests.py にインポートできるようにすることです。私は次のことを試みました:

from . import person
from .. import person
from .App.src import person
from ..App.src import person
from ..src.person import *
from ..src import person
from .src import person

上記のすべてが構文エラーをスローするか、

ValueError: Attempted relative import in non-package

誰かが私のためにこれを明確にしてもらえますか?

編集:Pythonのバージョンは2.7です。 編集:これをユニットテストやノーズと一緒に使用できるようにしたいと思います。

4

3 に答える 3

6

私の推測では (間違っていればこれを削除します)、person_tests.py次のようにして、パッケージ内のモジュールとしてではなく、トップレベルのスクリプトとして使用しようとしているということです。

$ cd App/tests
$ python person_tests.py

その場合、person_testsは としてApp.tests.person_testsではなく、そのまま(または、同じ基本的な問題を持つ__main__トップレベルの としてマイナーなバリエーションで) になります。person_testsしたがって、..は を参照しないため、相対インポートとしてAppを取得する方法はありません。person

より一般的にはPYTHONPATH、 を含む上.の何もパッケージ ディレクトリの途中に置くべきではありません。そうしないと、問題が発生します。

正しい答えは、それをしないことです。次のようにします。

$ python -m App.tests.person_tests

または、モジュールをインポートするトップレベル (パッケージ外) のスクリプトを作成し、そのトップレベルのスクリプトを実行します。

于 2013-08-05T23:12:00.557 に答える
1

abarnert が言うように、スクリプトの現在の名前に基づいて、相対インポートのメインとしてスクリプトを実行することはできません。ドキュメントから引用:

明示的および暗黙的な相対インポートは、現在のモジュールの名前に基づいていることに注意してください。メイン モジュールの名前は常に "__main__" であるため、Python アプリケーションのメイン モジュールとして使用するモジュールは、常に絶対インポートを使用する必要があります。

.現在のパッケージを..表し、親パッケージを表します。したがって、インポートステートメントの一部が間違っています。

from . import person # wrong for no person module in package tests
from .. import person # wrong for no person module in package app
from .App.src import person # wrong for no app package in package tests
from ..App.src import person # wrong for no app package in package app
from ..src.person import * # right
from ..src import person # right
from .src import person # wrong

相対インポートの基準については、PEP328を参照できます。

于 2013-08-05T23:25:49.973 に答える