5

パッケージの階層を持つアプリケーションがあります。パッケージ階層の上位にある他のモジュールを参照するモジュールはかなりの数あります。以下に例示するように、相対インポートを使用してこの問題を解決できます。ただし、テストのためにモジュールを直接実行すると、Attempted relative import in non-package例外が発生して失敗します。

モジュールをテスト用に個別に実行し、他のモジュールからインポートできるように、アプリケーションまたはインポートステートメントを整理するためのより良い方法はありますか?

\spam
    \morespam
        child.py
    base.py
\eggs
    user.py

base.py

class Base(object):
    def hello(self):
        print 'Um, wot?'

child.py

from ..base import Base       # references the parent package correctly, 
                              # but fails when this module is executed individually

class Child(Base):
    def hello(self):
        print 'Hello, world!'

if __name__ == '__main__':
    import unittest
    # ... unit test code ...

user.py

from spam.morespam.child import Child
print Child().hello()

既存のソリューション

階層の上位にあるモジュールを参照する必要があるモジュールの先頭に、次のヘッダーを追加できることがわかりました。

if __name__ == '__main__':
    import sys, os
    sys.path.append(os.path.abspath(os.path.join(sys.path[0], '..')))

欠点は、このコードをあちこちに追加する必要があることです。これは一定ではありません。'..'相対パスは、階層内のパッケージの深さによって異なります。

他の可能な解決策...

  1. アプリケーションルートを使用して.pthファイルを作成できます。残念ながら、これはPythonインストールのsite-packagesフォルダーに追加する必要があるため、アプリケーション固有ではありません。
  2. アプリケーションルートを一時的にPYTHONPATHに追加し、すべてのモジュールがルートからパッケージを参照するようにすることができます。ただし、これにより、を呼び出すだけでスクリプトを実行するという単純さがなくなりpython.exe whatever.pyます。
  3. インポートすると、アプリケーションのルートフォルダーでマーカーファイルを検索するようなモジュールを作成できます。次に、この汎用モジュールをローカルのPythonインストールにインストールして、アプリ内のすべてのモジュールにインポートできるため、実行しているモジュールに関係なく、ルートがPYTHONPATHにあることが保証されます。
4

2 に答える 2

1

__init__.pyインポート元のフォルダーに空のファイルとして追加する必要があります。これを行うと、Pythonはディレクトリをパッケージとして扱い、インポートステートメントで使用できるようになります。

\spam
    \morespam
        __init__.py
        child.py
    __init__.py
    base.py
\eggs
    __init__.py
    user.py

これを実行し、このディレクトリのベースへのPYTHONPATHを確立したら、次のインポートを実行できます。

base.py

from morespam.child import Child
from ..eggs import user

__init__.pyファイルが存在する必要があるだけですが、このファイルの変数を、スクリプトが使用しようとした場合にインポートするディレクトリ内のモジュールのリストとして定義することもでき__ALL__ますimport *

于 2011-08-19T13:59:57.377 に答える
1

私はこれをPyCharmで解決しました。これは、アプリケーションを実行するたびにソースルートをPYTHONPATHに自動的に追加します。私が知る限り、PyCharmは基本的に私のためにオプション#2を行います。

于 2011-10-31T21:05:44.893 に答える