回答:
以前はパッケージの必須部分でした(古い3.3より前の「通常のパッケージ」ではなく、新しい3.3 以降の「名前空間パッケージ」)。
Pythonは、通常のパッケージと名前空間パッケージの2種類のパッケージを定義しています。通常のパッケージは、Python 3.2以前に存在していた従来のパッケージです。通常のパッケージは、通常、
__init__.py
ファイルを含むディレクトリとして実装されます。通常のパッケージがインポートされると、この__init__.py
ファイルは暗黙的に実行され、ファイルが定義するオブジェクトはパッケージの名前空間の名前にバインドされます。この__init__.py
ファイルには、他のモジュールと同じPythonコードを含めることができます。Pythonは、インポート時にモジュールに属性を追加します。
しかし、リンクをクリックするだけで、例、詳細情報、および名前空間パッケージの説明が含まれます__init__.py
。
sys.path.insert(0, '/path/to/datetime')
、そのパスを、作成したディレクトリへのパスに置き換えます。今のようなものを試してくださいfrom datetime import datetime;datetime.now()
。AttributeErrorが表示されるはずです(現在、空のファイルをインポートしているためです)。空の初期化ファイルを作成せずにこれらの手順を繰り返すと、これは起こりません。それはそれが防ぐことを意図したものです。
from datetime import datetime
エラーなしで発行できない場合、何かが正しく設定されていません。バージョン2.3までは、これで十分です。
builtins
リストされます(docs.python.org/3/tutorial/modules.html#the-dir-functionを参照)。組み込みモジュールを一覧表示する場合は、(cf。docs.python.org/3/library/sys.html#sys.builtin_module_names)を実行します。import sys; print(sys.builtin_module_names)
名前__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
ファイルは通常空であるが、例えば上述した等方が便利名、ホールド簡易関数、下のパッケージの選択された部分をエクスポートするために使用することができ、初期化モジュールの内容は、以下のようにアクセスすることができ
import spam
基づいて、この
__init__.py
はPython 2.Xで必要でしたが、Python 2.7.12(私はテストしました)でも必要ですが、(申し立てによると)Python 3.3以降では不要になり、Python 3.4.3(Iそれをテストした)。詳細については、stackoverflow.com / questions / 37139786をご覧ください。
__init__.py
。
setup.py
していて使用するfind_packages()
場合は__init__.py
、すべてのディレクトリに存在する必要があります。stackoverflow.com/a/56277323/7127824を
Pythonパッケージとしてディレクトリを標識し、定義するだけで__all__
、__init__.py
あなたは、パッケージレベルで任意の変数を定義することができます。これは、パッケージがAPIのような方法で頻繁にインポートされるものを定義している場合に便利です。このパターンは、Pythonの「フラットは入れ子よりも優れている」という哲学の遵守を促進します。
以下は、私のプロジェクトの1つの例です。ここでは、データベースとやり取りするために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()
もちろん、これは少し便利です。代わりSession
に、データベースパッケージの「create_session.py」のような新しいファイルで定義し、次を使用して新しいセッションを開始します。
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
、「明示的なものは暗黙的なものよりも優れている」という哲学に違反しないようにするために、ファイルは非常に薄くすべきであると思われます。
engine
、sessionmaker
、create_engine
、およびos
すべてのもからインポートすることができdatabase
ますが、その名前空間の混乱を作ったようになりました...ようです。
__all__ = [...]
すると、でインポートされるものを制限できますimport *
。しかし、それとは別に、はい、厄介なトップレベルの名前空間が残ります。
2つの主な理由があります __init__.py
便宜上、他のユーザーは、パッケージ階層内での関数の正確な場所を知る必要はありません。
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 3.3以降__init__.py
、インポート可能なPythonパッケージとしてディレクトリを定義する必要がなくなりました。
PEP 420:Implicit Namespace Packagesを確認してください:
__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/
Is __init__。 Python 3のパッケージには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を関数と呼びました。__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
したがって、*インポートを使用すると、モジュールパッケージは__init__.py
コンテンツの対象になります。
from package_x.subPackage_b.module_n1 import function_X
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
toに変更した場合は、インポートするだけで__init__.py
使用できます。foo()
main_methods
import main_methods
print(main_methods.foo()) # Prints 'foo'
これ__init__.py
はパッケージの一部として扱われるため機能します。
一部のPythonパッケージは実際にこれを行います。例はJSONであり、実行import json
は実際にパッケージ__init__.py
からインポートされjson
ます(パッケージファイルの構造はこちらを参照してください):
ソースコード:
Lib/json/__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ファイルのインポートを容易にします。このファイルを他のpyファイルを含むディレクトリ(たとえばstuff)に配置すると、import stuff.otherのようなことができます。
root\
stuff\
other.py
morestuff\
another.py
__init__.py
ディレクトリstuff内にこれがないと、Pythonはstuffのソースコードの場所がわからず、それをパッケージとして認識できないため、other.pyをインポートできませんでした。
__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