私は次のソースコード構造を持っています
/testapp/
/testapp/__init__.py
/testapp/testmsg.py
/testapp/sub/
/testapp/sub/__init__.py
/testapp/sub/testprinter.py
ここで、testmsg
は次の定数を定義します。
MSG = "Test message"
およびsub/testprinter.py
:
import testmsg
print("The message is: {0}".format(testmsg.MSG))
しかし、私はImportError: No module named testmsg
パッケージ構造以来動作するはずではありませんか?各サブモジュールでsys.pathを実際に拡張したくはありませんし、相対インポートも使用したくありません。
ここで何が間違っていますか?
それはすべて、どのスクリプトrunに依存します。そのスクリプトのパスは、Pythonの検索パスに自動的に追加されます。
次の構造にします。
TestApp/
TestApp/README
TestApp/LICENSE
TestApp/setup.py
TestApp/run_test.py
TestApp/testapp/__init__.py
TestApp/testapp/testmsg.py
TestApp/testapp/sub/
TestApp/testapp/sub/__init__.py
TestApp/testapp/sub/testprinter.py
次に、TestApp/run_test.py
firstを実行します。
from testapp.sub.testprinter import functest ; functest()
次に、TestApp/testapp/sub/testprinter.py
でできること:
from testapp.testmsg import MSG
print("The message is: {0}".format(testmsg.MSG))
より良いヒント here ;
以下のような相対インポートを使用します
from .. import testmsg
この質問には答えがあります-動的インポート:
import sys
sys.path.append(path_to_parent)
import parent.file1
ここに何かをインポートするために作ったものがあります。もちろん、このスクリプトをローカルディレクトリにコピーしてインポートし、use
必要なパスを指定する必要があります。
import sys
import os
# a function that can be used to import a python module from anywhere - even parent directories
def use(path):
scriptDirectory = os.path.dirname(sys.argv[0]) # this is necessary to allow drag and drop (over the script) to work
importPath = os.path.dirname(path)
importModule = os.path.basename(path)
sys.path.append(scriptDirectory+"\\"+importPath) # Effing mess you have to go through to get python to import from a parent directory
module = __import__(importModule)
for attr in dir(module):
if not attr.startswith('_'):
__builtins__[attr] = getattr(module, attr)