__init__.pyPythonソースディレクトリの目的は何ですか?
12 に答える
これは、パッケージの必須部分でした( 3.3以降の新しい「名前空間パッケージ」ではなく、3.3より前の古い「通常のパッケージ」 )。
Pythonは、通常パッケージと名前空間パッケージの2種類のパッケージを定義しています。通常のパッケージは、Python3.2以前に存在していた従来のパッケージです。通常のパッケージは通常、ファイルを含むディレクトリとして実装され
__init__.pyます。通常のパッケージがインポートされると、この__init__.pyファイルは暗黙的に実行され、それが定義するオブジェクトはパッケージの名前空間の名前にバインドされます。この__init__.pyファイルには、他のモジュールに含めることができるのと同じPythonコードを含めることができ、Pythonは、モジュールがインポートされるときに、モジュールにいくつかの追加の属性を追加します。
ただし、リンクをクリックするだけで、例、詳細情報、および名前空間パッケージの説明が含まれています。これは、のないパッケージの種類です__init__.py。
指定されたファイル__init__.pyは、ディスク上のディレクトリを Python パッケージ ディレクトリとしてマークするために使用されます。ファイルがある場合
mydir/spam/__init__.py
mydir/spam/module.py
パス上にあり、コードを次のようmydirにインポートできますmodule.py
import spam.module
また
from spam import module
ファイルを削除すると__init__.py、Python はそのディレクトリ内でサブモジュールを検索しなくなるため、モジュールをインポートしようとすると失敗します。
__init__.pyファイルは通常空ですが、パッケージの選択した部分をより便利な名前でエクスポートしたり、便利な関数を保持したりするために使用できます。上記の例を考えると、init モジュールの内容には次のようにアクセスできます。
import spam
これに基づいて
ディレクトリを Python パッケージとしてラベル付けしてを定義するだけでなく__all__、__init__.pyでは、パッケージ レベルで任意の変数を定義できます。API のような方法で頻繁にインポートされるものをパッケージが定義している場合、これは便利なことがよくあります。このパターンは、Pythonic の「ネストよりもフラットの方が優れている」という哲学への順守を促進します。
例
これは私のプロジェクトの 1 つからの例です。このプロジェクトでは、データベースと対話するためにsessionmaker呼び出された を頻繁にインポートします。Sessionいくつかのモジュールを含む「データベース」パッケージを作成しました。
database/
    __init__.py
    schema.py
    insertions.py
    queries.py
My__init__.pyには次のコードが含まれています。
import os
from sqlalchemy.orm import sessionmaker
from sqlalchemy import create_engine
engine = create_engine(os.environ['DATABASE_URL'])
Session = sessionmaker(bind=engine)
ここで定義したのでSession、次の構文を使用して新しいセッションを開始できます。このコードは、「データベース」パッケージ ディレクトリの内部または外部から実行されたものと同じです。
from database import Session
session = Session()
もちろん、これはちょっとした便利な方法です。別の方法Sessionとして、データベース パッケージで「create_session.py」などの新しいファイルを定義し、次を使用して新しいセッションを開始することもできます。
from database.create_session import Session
session = Session()
参考文献
ここの適切な使用法をカバーする非常に興味深いredditスレッドがあり__init__.pyます:
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
大多数の意見は__init__.py、「明示的は暗黙的よりも優れている」という哲学に違反することを避けるために、ファイルは非常に薄くする必要があるようです。
この__init__.pyファイルにより、Python はそれを含むディレクトリをモジュールとして扱います。
さらに、これはモジュールに読み込まれる最初のファイルであるため、モジュールが読み込まれるたびに実行するコードを実行したり、エクスポートするサブモジュールを指定したりするために使用できます。
Python では、パッケージの定義は非常に単純です。Java と同様に、階層構造とディレクトリ構造は同じです。しかし、あなたは__init__.pyパッケージに入っている必要があります。__init__.py以下の例でファイルを説明します。
package_x/
|--  __init__.py
|--    subPackage_a/
|------  __init__.py
|------  module_m1.py
|--    subPackage_b/
|------  __init__.py
|------  module_n1.py
|------  module_n2.py
|------  module_n3.py
__init__.py存在する限り、空にすることができます。ディレクトリをパッケージと見なす必要があることを示します。もちろん、__init__.py適切なコンテンツも設定できます。
module_n1 に関数を追加すると、次のようになります。
def function_X():
    print "function_X in module_n1"
    return
実行後:
>>>from package_x.subPackage_b.module_n1 import function_X
>>>function_X()
function_X in module_n1 
次に、階層パッケージに従い、module_n1 関数を呼び出しました。__init__.py次のように subPackage_b で使用できます。
__all__ = ['module_n2', 'module_n3']
実行後:
>>>from package_x.subPackage_b import * 
>>>module_n1.function_X()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named module_n1
したがって、* import を使用すると、モジュール パッケージが__init__.pyコンテンツの対象になります。
他のPythonファイルのインポートを容易にします。このファイルを他のpyファイルを含むディレクトリ(たとえば、stuff)に配置すると、importstuff.otherのようなことができます。
root\
    stuff\
         other.py
    morestuff\
         another.py
ディレクトリスタッフ内にこれ__init__.pyがないと、Pythonはスタッフのソースコードがどこにあるかを認識せず、パッケージとして認識できないため、other.pyをインポートできませんでした。