2017-03-19 30 views
2

私は何かをしようとしていますが、私はPythonについていくつかの問題を見逃していると思います(2.7を使用していますが、可能なら)。Pythonのモジュールの相対パス

私はパッケージやモジュールのような用語についてはわかりませんが、私にとっては以下のことはかなりシンプルなものです。

これは、ディレクトリ構造である:私はすべてこの「相対を実行したいと思います

def do_stuff(): 
    print("This should be in stdout") 

. 
├── job 
│   └── the_script.py 
└── modules 
   ├── __init__.py 
   └── print_module.py 

the_script.pyの内容:

# this does not work 
import importlib 
print_module = importlib.import_module('.print_module', '..modules') 

# this also does not work 
from ..modules import print_module 

print_module.do_stuff() 

print_moduleの内容パス "のようなもの:

/job$ python2 the_script.py 

しかしimportlib.import_moduleは、さまざまなエラーを与える:

  • 私はちょうど1つの入力パラメータ..modules.print_moduleを使用する場合は、Iが得る:TypeError("relative imports require the 'package' argument")
  • I(上記の例のように)2つの入力パラメータを使用する場合、その後、私が取得:ValueError: Attempted relative import in non-package:一方ValueError: Empty module name

は私が手from ..modules構文を使用して。

私は__init__.py空のファイルは "パッケージ"(またはモジュールについてはわかりませんが、用語についてはわかりません)としてそのコードを修飾するのに十分なはずだと思いますが、相対パスを管理する方法について何か不足しているようです。

私は過去の人にimport osimport sysからpathや他の機能を使用して、これをハッキングされましたが、公式ドキュメント(のpython 2.7および3 *)によると、これはもはや必要ではないことをお読みください。

私は何が間違っていますか?modules/print_module.do_stuffの内容を「相対ディレクトリ」のスクリプトから呼び出すとどうなりますかjob/?あなたはここで、このガイドの構造に従っている場合

+0

なぜimportlibをここで使用しますか?なぜそれを直接インポートしないのですか? –

+1

'__init __。py'は、それが入っているディレクトリのパッケージを作成するだけです。表示したツリーの*すべてのディレクトリに' __init __。py'を追加する必要があります。また、トップレベルのパッケージディレクトリを含むディレクトリが 'sys.path'にあることを確認する必要があります。また、ファイルの1つをスクリプトとして実行できるようにするには、問題について考える必要があります記載されている[ここ](http://stackoverflow.com/questions/11536764/how-to-fix-attempted-relative-import-in-non-package-even-with-init-py)と[here](http: //stackoverflow.com/questions/14132789/relative-imports-for-the-billionth-time)。 – BrenBarn

答えて

1

sysosを使用して解決策が見つかりました。

スクリプトthe_script.pyは次のようになります。私は、パスなどで午前どこ

import sys 
import os 
lib_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '../modules')) 
sys.path.append(lib_path) 

# commenting out the following shows the `modules` directory in the path 
# print(sys.path) 

import print_module 

print_module.do_stuff() 

は、その後、私は関係なく、コマンドラインを介して、それを実行することはできません。

  • /job$ python2 the_script.py
  • <...>/job$ python2 <...>/job/the_script.py
1

:あなたのケースで翻訳

To give the individual tests import context, create a tests/context.py file:

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

import sample 

Then, within the individual test modules, import the module like so:

from .context import sample 

This will always work as expected, regardless of installation method.

この意味:

root_folder 
├── job 
│ ├── context.py <- create this file 
│ └── the_script.py 
└── modules 
    ├── __init__.py 
    └── print_module.py 
http://docs.python-guide.org/en/latest/writing/structure/#test-suiteあなたがこれを見ます(非常に、それは非常に便利です、それはすべてを読むことをお勧めします) context.pyファイルで

は、上記の行を書くが、import modules代わりにimport samples

Fiのあなたのthe_script.py:ナンバーfrom .context import moduleで、あなたは行くように設定されます!

幸運:)

+0

ありがとう:)しかし、これは: 'ImportError:modules.print_moduleという名前のモジュールがありません.' – TPPZ

+0

私の答えが更新されました。 –

+0

Python 2では、これは 'ImportError:Airflow_stuff.modules.print_module'という名前のモジュールをPython 3に提供します。同様のエラーメッセージを返します。 – TPPZ

1

あなたは専門用語がわからない場合は非常に素晴らしいチュートリアルに行く:

http://docs.python-guide.org/en/latest/writing/structure/#modules

http://docs.python-guide.org/en/latest/writing/structure/#packages

しかし、あなたの構造について:

. 
├── job 
│ └── the_script.py 
└── modules 
    ├── __init__.py 
    └── print_module.py 

はちょうどthe_script.pyで言う:

import sys 
sys.append('..') 
import modules.print_module 

これはPYTHONPATHに親ディレクトリを追加し、Pythonはジョブディレクトリにディレクトリ「パラレル」を見て、それが動作します。

私は、最も基本的なレベルで、それを知っているsufficentであることを考える:

  1. パッケージ__init__.pyファイル
  2. モジュールを持つ任意のディレクトリには、.pyを持つファイルですが、あるときにされ拡張モジュールを省略したモジュールをインポートしています。
+0

ドキュメントを指摘してくれてありがとう:)しかし、これは次のようなものです: 'ImportError:modulesという名前のモジュールはありません。print_module' – TPPZ

+0

私は答えを訂正しました:) – jedruniu

+1

Python 2ではこれは 'AttributeError: 'module'オブジェクトには属性 'append''がありませんが、' sys.path.append(' .. ') 'の代わりにImportError:modules.print_moduleという名前のモジュールはありません。 Python 3では、同様のエラーメッセージが表示されます。 – TPPZ