Djangoのモデルシステムがどのように機能するかを調べていますが、理解できないことに気付きました。
空の__init__.py
ファイルを作成して、現在のディレクトリがパッケージであることを指定することを知っています。また、インポート*が正しく機能するように、__init__.py
に変数を設定できます。
しかしDjangoはfrom ... import ...ステートメントの束を追加し、__init__.py
でクラスの束を定義します。これは、物事を面倒に見せるだけではありませんか? __init__.py
にこのコードが必要な理由がありますか?
__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
で割り当てられたすべての名前は、インポートされたモジュール、関数、またはクラスにかかわらず、パッケージまたはパッケージ内のモジュールをインポートするたびにパッケージ名前空間で自動的に使用可能になります。
それは本当に個人的な好みであり、pythonモジュールのレイアウトに関係しています。
erikutils
というモジュールがあるとします。モジュールになる方法は2つあります。sys.path
にerikutils.pyというファイルがあるか、またはerikutilsというディレクトリがあります。 sys.path
に空の__init__.py
ファイルが含まれています。次に、fileutils
、procutils
、parseutils
という名前のモジュールがあり、それらをerikutils
の下のサブモジュールにしたいとします。したがって、fileutils.py、procutils.py、およびparseutils.pyと呼ばれる.pyファイルを作成します。
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 *フィールドクラスは__init__.py
Django/db/models/fieldsディレクトリに定義されています。すべてを仮想的なDjango/db/models/fields.pyモデルに詰め込みたくなかったので、彼らはこれをやったと思うので、いくつかのサブモジュールに分割しました(関連.py、files.pyなど)、作成された* Field定義をfieldsモジュール自体に貼り付けました(したがって、__init__.py
)。
__init__.py
ファイルを使用すると、内部のパッケージ構造を外部から見えなくすることができます。内部構造が変更された場合(たとえば、1つのファットモジュールを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
外部からは、パッケージは以前とまったく同じように見えます。