__init__.py
Pythonソースディレクトリの目的は何ですか?
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をインポートできませんでした。