94

django のモデル システムがどのように機能するかを調べていますが、理解できないことに気付きました。

__init__.py空のファイルを作成して、現在のディレクトリがパッケージであることを指定していることは知っています。__init__.pyまた、 import * が適切に機能するように変数を設定できます。

しかし、django は一連の from ... import ... ステートメントを追加し、__init__.py. なんで?これは物事が乱雑に見えるだけではありませんか?でこのコードが必要な理由はあり__init__.pyますか?

4

3 に答える 3

78

__init__.pyそれを含むパッケージ (ディレクトリ) をインポートすると、すべてのインポートが利用可能になります。

例:

./dir/__init__.py:

import something

./test.py:

import dir
# can now use dir.something

編集:言及するのを忘れていましたが、コードは、__init__.pyそのディレクトリからモジュールを初めてインポートしたときに実行されます。そのため、通常、パッケージ レベルの初期化コードを配置するのに適した場所です。

EDIT2: dgrant は、私の例で混乱の可能性を指摘しました。では__init__.py import something、パッケージから不要な任意のモジュールをインポートできます。たとえば、これを に置き換えるとimport datetime、最上位レベルtest.pyでこれらのスニペットの両方が機能します。

import dir
print dir.datetime.datetime.now()

import dir.some_module_in_dir
print dir.datetime.datetime.now()

つまり、インポートされたモジュール、関数、クラスなど、 で割り当てられたすべての名前は__init__.py、パッケージまたはパッケージ内のモジュールをインポートするたびに、パッケージの名前空間で自動的に使用可能になります。

于 2008-09-23T04:47:51.010 に答える
39

これは本当に個人的な好みであり、Pythonモジュールのレイアウトと関係があります。

と呼ばれるモジュールがあるとしましょうerikutils。モジュールにする方法は2つあります。erikutils.pyというファイルがあり、erikutilsというディレクトリsys.pathがあり、その中に空のファイルがあります。次に、、と呼ばれるモジュールがたくさんあり、それらをの下のサブモジュールにしたいとします。したがって、 fileutils.pyprocutils.py、およびparseutils.pyという名前の.pyファイルを作成します。sys.path__init__.pyfileutilsprocutilsparseutilserikutils

erikutils
  __init__.py
  fileutils.py
  procutils.py
  parseutils.py

fileutils、、、procutilsまたはparseutilsモジュールに属していない関数がいくつかあるかもしれません。そして、と呼ばれる新しいモジュールを作成する気がないとしましょうmiscutils。そして、次のように関数を呼び出せるようにします。

erikutils.foo()
erikutils.bar()

するのではなく

erikutils.miscutils.foo()
erikutils.miscutils.bar()

モジュールはファイルではなくディレクトリであるためerikutils、ファイル内でその機能を定義する必要があり__init__.pyます。

djangoで、私が考えることができる最良の例はですdjango.db.models.fields。すべてのdjango*Fieldクラスは、 django / db / models/fieldsディレクトリの__init__.pyファイルで定義されています。彼らはすべてを架空のdjango/db / models / fields.pyモデルに詰め込みたくなかったので、これを行ったと思います。そのため、いくつかのサブモジュール(related.pyfiles.pyなど)に分割し、作成された*Field定義をfieldsモジュール自体に貼り付けました(したがって、)。__init__.py

于 2008-09-23T06:12:15.080 に答える
29

この__init__.pyファイルを使用すると、パッケージの内部構造を外部から見えなくすることができます。内部構造が変更された場合 (たとえば、1 つの fat モジュールを 2 つに分割したため)、__init__.pyファイルを調整するだけでよく、パッケージに依存するコードは調整しません。パッケージの一部を非表示にすることもできます。たとえば、一般的な使用の準備が整っていない場合などです。

コマンドを使用できることに注意してください。そのdelため、典型的な例は次の__init__.pyようになります。

from somemodule import some_function1, some_function2, SomeObject

del somemodule

somemodule新しいものを分割することにした場合は、次の__init__.pyようになります。

from somemodule1 import some_function1, some_function2
from somemodule2 import SomeObject

del somemodule1
del somemodule2

外から見ると、パッケージは以前とまったく同じように見えます。

于 2008-09-24T11:02:55.747 に答える