web-dev-qa-db-ja.com

Python 2.7での「絶対インポート」の正しい方法

  • Python 2.7.10
  • Virtualenv内
  • 各モジュールでfrom __future__ import absolute_importを有効にする

ディレクトリツリーは次のようになります。

Project/
    prjt/
        __init__.py
        pkg1/
            __init__.py
            module1.py
            tests/
                __init__.py
                test_module1.py
        pkg2/
            __init__.py
            module2.py
            tests/
                __init__.py
                test_module2.py
        pkg3/
            __init__.py
            module3.py
            tests/
                __init__.py
                test_module3.py
    data/
    log/

次のように書くことで、pkg2/module2.pypkg1/module1.pyの関数compute()を使用しようとしました:

# In module1.py
import sys
sys.path.append('/path/to/Project/prjt')

from prjt.pkg2.module2 import compute

しかし、python module1.pyを実行すると、インタプリタはNo module named prjt.pkg2.module2というImportErrorを発生させました。

  1. 「絶対インポート」の正しい方法は何ですか? Projectへのパスをsys.pathに追加する必要がありますか?
  2. インタラクティブインタープリタでtest_module1.pyを実行するにはどうすればよいですか? python prjt/pkg1/tests/test_module1.pyまたはpython -m prjt/pkg1/tests/test_module1.pyによる?
27
Zelong

方法pythonモジュールを見つける

pythonはsys.pathからモジュールを検索し、最初のエントリsys.path[0] is ''は、pythonが現在のモジュールを検索することを意味します作業ディレクトリ

import sys
print sys.path

およびpython site-packagesからサードパーティモジュールを検索

だから絶対インポートするには、

_sys.pathにパッケージを追加します

import sys
sys.path.append('the_folder_of_your_package')

import module_you_created

module_you_created.fun()

エクスポートPYTHONPATH

pYTHONPATHは実行前にsys.pathにインポートされます

export PYTHONPATH=the_folder_of_your_package

import sys
[p for p in sys.path if 'the_folder_of_your_package' in p]

対話型インタープリターでtest_module1.pyを実行するにはどうすればよいですか? python Project/pkg1/tests/test_module1.pyまたはpython -m Project/pkg1/tests/test_module1.py?

あなたはif __name__ == '__main__':慣用的な方法を使用でき、python Project/pkg1/tests/test_module1.pyを使用できます

if __name__ = '__main__':
    main()
15
Sean

sys.path.append('path/to/Project')prjt/__init__.pyに追加する場合は、サブモジュールをインポートする必要があります:from pkg2.module2 import computeprjt指定なし)prjtパッケージのインポートが進行状況があり、上位レベルのフォルダーがsys.pathにありません。これはまさに@Cissoidが示唆したことです。

ところで、Py> = 3.0の場合、from __future__ import absolute_importは不要です。


2番目の質問に答えます...私はunittestsサブフォルダーの構造が非常に似ているため、pkg/unittests/testall.pyに次のように書きました。

testfolder = os.path.abspath(os.path.dirname(__file__))
project_root = os.path.abspath(os.path.join(testfolder, r"..\.."))
sys.path.append(project_root)
import pkg

-mオプションなしで実行します。不要な複雑化のためです。

7
Vasily Ryabov

外部プロジェクトパスをインポートします。

sys.path.append('/path/to/Project')

または、pkg2から "compute" startをインポートします

from pkg2.module2 import compute
6
Cissoid

これを試して

import os, sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

これは絶対パスを与えます

2
Atul Jain

明示的な相対インポートを使用すると、これはmodule1.pyから機能するはずです。

from ..pkg2.module2 import compute()

これはPYTHONPATH...をいじるよりもきれいです。

0
FabienP