2012-04-21 6 views
5

パッケージを書きます。Pのルートにモジュールm0があります。同じパッケージ内の別のモジュールからパッケージ階層のルートにあるPythonモジュールをインポートする最も良い方法

from P.m0 import ... 

私はPIの名前を変更するただし場合: はどこかP内部のモジュールM1、M2、...もちろんM0

からインポートする必要があり、私はこれらのモジュールのそれぞれに書き込むことができますがありますすべての場所を再訪し、そのようなステートメントを書き直さなければならない。

相対インポートも使用できますが、モジュールをパッケージ階層内の別のレベルに移動すると、ドット数を修正する必要があります。

他にもいくつかの理由がありますが、私は実際に私のパッケージのルートにあるモジュールm0からインポートすると言っていますが、これを表現する最良の方法は何ですか?

+0

'sysを変更する' import x'のような非常に内省的なハックを書くのは簡単ではありません。http://docs.python.org/library/functions.html#__import__で提案されているように、 'builtin .__ import__'のセマンティクスをオーバーライドしたりインポートフックを作成したりすると、存在しない非常に合理的な機能を探しています私の謙虚な意見では、Pythonは他の言語よりも適していますが、非冗長なインポートには特に適していません。そのような冗長さが明白で、したがって良いものであるという「ピジョン(pythonic)」という見解は、おそらくこの特徴を明らかにするものではない。 – ninjagecko

+0

私はこれについて大きな問題があると知っていましたが、とにかく大きなリファクタリングを行っています。コードを書くことは、常に大きなリファクタリングです。いくつかのパッケージを使って作業し、ある場所に何かを置いてから、他の場所で使うことができる主要な機能だと分かっているので、別のパッケージでそれをリファクタリングします。あなたが物事を動かすときに心配する必要がある多くの事があります。私はオーバーヘッドを最小限に抑えようとしています。 ところで、すべてのパッケージの先頭にm0があります。そのため、モジュールが別のパッケージに移動しても、最初のパッケージの先頭のm0を参照すると、エラーが発生しやすくなります。 – gae123

+0

はい、同意します。しかし、なぜあなたが言っていることを言っているのか分かりません。私は「これについて大したことは何か」と尋ねていませんでした。 – ninjagecko

答えて

1

これはできません。

しかし、相対的なインポートを更新する必要があるサブパッケージ間でモジュールを移動する大きなリファクタリングを実行すると大きな問題にはなりません。

相対インポートを使用しない場合はトップレベルのパッケージ名の変更にも同じことが適用されます。これはすべてのファイルに対して検索と置換を行うと非常に高速に実行できます。

+0

合意 - 'import'は、すばやい検索と置換によって処理できるユースケースを修正する余分な魔法を追加することなく、十分に複雑です。 – katrielalex

0

ご質問を少しでも修正したい場合は、この問題を解決できます。

パッケージのエントリポイントのみが制御されている場合。例えば

import sys 
import os.path 
packageDir = os.path.split(__name__)[0] 
sys.path[:] = sys.path+[packageDir] # or maybe you want it first... 

メイン:あなたが唯一のでしょう

testsuite package/.../module.pyを呼び出すような何かをすることによって、あなたのコードをテストTHENあなたが最初に行う事がimport firstthingで、パッケージに/ firstthing.pyあなたが持っていることを確認することができますあなたのエントリーポイントを通らずにpythonファイルを実行することができないことに注意してください。私はいつもPythonで書く(相対的なインポートがうまくいくようにする)すべてのプロジェクトでこれをしたいと思っていますが、私は個人的にこれをとても不便に思っています。


第2の選択肢もあります。 あなたのパッケージがpythonパスに別のパッケージを必要としていると指定するのは無理です。このパッケージは、大規模なハッキングを実行するユーティリティパッケージである可能性があります。たとえば、パッケージの名前が "x"の場合、import xを実行すると、inspectモジュールを使用してインタプリタスタックを反映させ、どのモジュールからインポートしたかを把握できます。次に、パッケージのルートが見つかるまで(何らかの特別なインジケータファイルやマニフェストなどを確認することによって)親ディレクトリを上っていくことで、ある種の "後方のos.walk"を行うことができます。その後、コードはプログラムによって、上記のpythonパスの変更をsys.pathで実行します。上記と同じですが、あなたはひどいエントリーポイントを通過することなく、任意のpythonファイルを実行するようなことをする自由を持っています。

シェル環境を極端にコントロールしている場合は、パッケージディレクトリをインクルードするために$ PYTHONPATHを追加することもできますが、これは多くの点で非常に脆弱です。

関連する問題