Pythonのソースディレクトリで__init__.py
とは何ですか?
これは、パッケージの必須部分でした( 古い、3.3より前の "通常のパッケージ" 、ない 新しい3.3+ "名前空間パッケージ" )。
Pythonは2種類のパッケージ、通常のパッケージと名前空間パッケージを定義しています。通常のパッケージは、Python 3.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の「フラットは入れ子になっているよりも優れている」という考え方に従うことを促進します。
これは私のプロジェクトの一例です。私はデータベースとやり取りするためにsessionmaker
と呼ばれるSession
を頻繁にインポートしています。私はいくつかのモジュールで "データベース"パッケージを書きました:
database/
__init__.py
schema.py
insertions.py
queries.py
私の__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()
もちろん、これはちょっとした便利さです - 私のデータベースパッケージの "create_session.py"のような新しいファイルでSession
を定義し、次のようにして新しいセッションを開始することです。
from database.create_session import Session
session = Session()
ここで__init__.py
の適切な使用法をカバーしている非常に興味深いredditスレッドがあります:
http://www.reddit.com/r/Python/comments/1bbbwk/whats_your_opinion_on_what_to_include_in_init_py/
大多数の意見は、__init__.py
ファイルは「明示的な方が暗黙的より優れている」という考え方に違反しないように非常に薄くするべきだと考えているようです。
__init__.py
には2つの主な理由があります
便宜上、他のユーザーはパッケージ階層内での関数の正確な位置を知る必要はありません。
your_package/
__init__.py
file1.py/
file2.py/
...
fileN.py
# in __init__.py
from file1 import *
from file2 import *
...
from fileN import *
# in file1.py
def add():
pass
それから他の人はadd()を呼び出すことができます。
from your_package import add
file1を知らなくても、
from your_package.file1 import add
何かを初期化したいのなら;例えば、ロギング(これはトップレベルに置かれるべきです):
import logging.config
logging.config.dictConfig(Your_logging_config)
__init__.py
ファイルにより、Pythonはそれを含むディレクトリをモジュールとして扱います。
さらに、これはモジュールにロードされる最初のファイルなので、モジュールをロードするたびに実行したいコードを実行したり、エクスポートするサブモジュールを指定したりするのに使用できます。
Python 3.3以降、__init__.py
はディレクトリをインポート可能なPythonパッケージとして定義する必要がなくなりました。
チェック PEP 420:暗黙のネームスペースパッケージ :
__init__.py
マーカーファイルを必要とせず、自動的に複数のパスセグメントにまたがることができるパッケージディレクトリのネイティブサポート( PEP 420 で説明されているように、名前空間パッケージに対するさまざまなサードパーティのアプローチに触発)
これがテストです。
$ mkdir -p /tmp/test_init
$ touch /tmp/test_init/module.py /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
├── module.py
└── __init__.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
$ rm -f /tmp/test_init/__init__.py
$ tree -at /tmp/test_init
/tmp/test_init
└── module.py
$ python3
>>> import sys
>>> sys.path.insert(0, '/tmp')
>>> from test_init import module
>>> import test_init.module
参照先
https://docs.python.org/3/whatsnew/3.3.html#pep-420-implicit-namespace-packages
https://www.python.org/dev/peps/pep-0420/
Python 3のパッケージには__init__.pyは不要ですか?
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という関数を呼び出しました。 subPackage_bで__init__.py
を次のように使用できます。
__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
そのため、* importingを使用して、モジュールパッケージは__init__.py
コンテンツの影響を受けます。
__init__.py
は、それが存在するディレクトリをロード可能なモジュールとして扱います。
コードを読むのを好む人のために、 Two-Bit Alchemistの をここに入れます。
$ find /tmp/mydir/
/tmp/mydir/
/tmp/mydir//spam
/tmp/mydir//spam/__init__.py
/tmp/mydir//spam/module.py
$ cd ~
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
>>> module.myfun(3)
9
>>> exit()
$
$ rm /tmp/mydir/spam/__init__.py*
$
$ python
>>> import sys
>>> sys.path.insert(0, '/tmp/mydir')
>>> from spam import module
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ImportError: No module named spam
>>>
Pythonは__init__.py
ファイルがなくても動作しますが、それでも含める必要があります。
パッケージはモジュールとして扱われるべきであることを指定しているので、それを含めます(空であっても)。
実際に__init__.py
ファイルを使用する場合もあります。
あなたが次のファイル構造を持っていたと想像してみてください。
main_methods
|- methods.py
そしてmethods.py
はこれを含んでいました:
def foo():
return 'foo'
foo()
を使うには、次のどれかが必要です。
from main_methods.methods import foo # Call with foo()
from main_methods import methods # Call with methods.foo()
import main_methods.methods # Call with main_methods.methods.foo()
たぶんそこにmethods.py
をmain_methods
(例えばランタイム/依存関係)の中に保持する必要がある(あるいは欲しい)が、あなたはmain_methods
をインポートしたいだけかもしれません。
methods.py
の名前を__init__.py
に変更した場合は、main_methods
をインポートするだけでfoo()
を使用できます。
import main_methods
print(main_methods.foo()) # Prints 'foo'
__init__.py
はパッケージの一部として扱われるため、これは機能します。
いくつかのPythonパッケージは実際にこれを行います。例は _ json _ です。ここでimport json
を実行すると実際にjson
パッケージから__init__.py
をインポートします( ここでパッケージファイル構造を参照してください )
ソースコード:
Lib/json/__init__.py
それは他のpythonファイルのインポートを容易にします。このファイルを他のpyファイルを含むディレクトリ(ものと言います)に置いたら、import stuff.otherのようなことができます。
root\
stuff\
other.py
morestuff\
another.py
この__init__.py
がディレクトリstuffの中にないと、other.pyをインポートすることはできません。なぜなら、Pythonはstuffのソースコードがどこにあるのかを知らず、それをパッケージとして認識できないからです。
__init__.py
ファイルはインポートを簡単にします。パッケージ内に__init__.py
がある場合は、関数a()
をファイルb.py
からインポートできます。
from b import a
それがなければ、しかし、あなたは直接インポートすることはできません。システムパスを修正する必要があります。
import sys
sys.path.insert(0, 'path/to/b.py')
from b import a