2009-07-20 8 views
4

(/ジャンゴ)Pythonで一貫性のないファイルのインポート・パスを使用するように強制:は、それは、ファイル図を用いて説明する方が良いでしょう...私は最近、ジャンゴの私の輸入(パイソン)といくつかの問題を抱えてきた

- project/ 
    - application/ 
     - file.py 
    - application2/ 
     - file2.py 
私は、次のしている project/application/file.py

:私は上からメソッドをインポートしようとすると、

def test_method(): 
    return "Working" 

を問題は、project/application2/file2.pyで発生します。

from application.file import test_method 

通常は動作しますが、時には動作しません。

from project.application.file import test_method 

しかし、プロジェクトフォルダは常に同じ名前でなければならないため、Djangoの移植性ガイドラインに反します。

私は気にしませんが、この問題は一貫して発生していません。ほとんどの場合、projectを省略すると大丈夫ですが、時には(そして、私が見る限りでは、理由はありません)。

私は何か愚かなことをかなり保証することができますが、これを経験した人はいますか?物事の一貫性を保つために、すべての関連輸入品の前にprojectを置くだけでいいのですか?正直なところ、projectのフォルダ名が変更されることはまずありません。できるだけガイドラインを守りたいだけです。

+0

PYTHONPATHの設定は、動作しているときと動作していないときを含めてください。 –

答えて

4

モジュールを見つけるためにインポートするには、sys.pathに入る必要があります。通常これは ""を含んでいるので、現在のディレクトリを検索します。プロジェクトから "application"をロードすると、現在のディレクトリにあるので、アプリケーションを見つけます。

これは明らかなことです。困ったことに、Pythonはどのモジュールがロードされたかを記憶しています。アプリケーションをロードすると、アプリケーションを読み込むapplication2をロードすると、モジュール "application"はすでにロードされています。それをディスク上で見つける必要はありません。すでにロードされているものだけを使用します。一方、まだアプリケーションをロードしなかった場合、アプリケーションをロードするものと同じディレクトリ(「。」)にないので、アプリケーションを検索しません。パス。

これは、インポートが動作することがあり、ときどき動作しないという奇妙なケースにつながる可能性があります。既にロードされている場合にのみ機能します。

これらのモジュールを「アプリケーション」としてロードできるようにするには、project /をsys.pathに追加する必要があります。

(相対輸入は関連聞こえるが、アプリケーションとアプリケーション2が別々のパッケージされているようにそれはそう - 。相対的な輸入品は、同じパッケージ内のインポートに使用されている)

最後に、一貫として全体のことを処理するようにしてくださいパッケージを作成したり、各アプリケーションを一貫して独自のパッケージとして扱うことができます。混同しないでください。パッケージ/がパスにある場合(例えば、sys.pathにpackage/..が含まれている場合)、実際には "package.application import foo"から実行できますが、 "from application import foo" Pythonはこれを認識しないため同じものです。名前が異なり、パスが異なるため、2つの別個のコピーがロードされてしまいます。間違いはありません。

0

project.app.modelsと同じ方法でインポートすることをお勧めします。モジュールを2回インポートすると、this questionで説明されているような不明瞭なエラーが発生することがあります。

+0

ああ、Django自体は、プロジェクトディレクトリ*に* __init __。py'ファイルを入れ、プロジェクトディレクトリをsys.pathに置くことでこれを解決します。常にプロジェクト名を省略するのは正しいことですが、それはDjangoの部分ではまだまだ厄介なことです(プロジェクトディレクトリから '__init __。py'ファイルを省略したはずです) – ncoghlan

2

djangoの哲学を掘り下げてみると、プロジェクトはアプリの集合であることがわかります。これらのアプリの中には他のアプリに依存するものもありますが、これは問題ありません。しかし、あなたが常に望むのは、アプリケーションをプラグイン可能にして、別のプロジェクトに移動してそこで使うことができるようにすることです。これを行うには、プロジェクトに関連するコード内のすべてのものを削除する必要があります。

from aplication.file import test_method 

これはこれを行うジャンゴの方法です。グレンはなぜあなたがあなたのエラーを得ているのかと答えたので、私はその部分に行きません。新しいプロジェクトを開始するコマンドを実行すると:

django-admin.py startproject myproject
これは、djangoに必要なmanage.py設定のファイル群を含むフォルダを作成しますが、別のことがあります。それは、あなたのpythonパスに "myproject"というフォルダを置きます。要するに、これはあなたがそのフォルダに入れたアプリケーションの中で、上記のようにインポートできることを意味します。何も魔法が起きなくても、django-admin.pyを使ってプロジェクトを開始する必要はありません。それは単なるショートカットです。アプリケーションフォルダは実際にどこにでも置くことができ、Pythonパス上に置く必要があるため、直接インポートしてコードプロジェクトを独立させることができ、将来のプロジェクトでも簡単に使用でき、DRYの原則そのdjangoが構築されています。

関連する問題