web-dev-qa-db-ja.com

__init__.pyはPython 3.3+のパッケージには必要ありません

私はPython 3.5.1を使っています。私はここでドキュメントとパッケージのセクションを読みます: https://docs.python.org/3/tutorial/modules.html#packages

今、私は次のような構造になっています。

/home/wujek/Playground/a/b/module.py

module.py

class Foo:
    def __init__(self):
        print('initializing Foo')

今、/home/wujek/Playgroundにいる間:

~/Playground $ python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x100a8f0b8>

同様に、現在は自宅で、Playgroundのスーパーフォルダーになります。

~ $ PYTHONPATH=Playground python3
>>> import a.b.module
>>> a.b.module.Foo()
initializing Foo
<a.b.module.Foo object at 0x10a5fee10>

実際、私はあらゆる種類のことができます。

~ $ PYTHONPATH=Playground python3
>>> import a
>>> import a.b
>>> import Playground.a.b

なぜこれが機能するのですか? Pythonのパスがaフォルダーを指しているときに__init__.pyをインポート可能にするには、bPlaygroundの両方にmodule.pyファイル(空のファイルでも問題ありません)が必要ですが?

これはPython 2.7から変わったようです。

~ $ PYTHONPATH=Playground python
>>> import a
ImportError: No module named a
>>> import a.b
ImportError: No module named a.b
>>> import a.b.module
ImportError: No module named a.b.module

__init__.py~/Playground/aの両方に~/Playground/a/bがあれば問題なく動作します。

123
wujek

Python 3.3+には Implicit Namespace Packages があり、__init__.pyファイルなしでパッケージを作成することができます。

暗黙の名前空間パッケージを許可することは、__init__.pyファイルを提供するという要件を完全に削除して影響を受ける可能性があることを意味します。

__init__.pyファイルを使った古い方法は、まだPython 2のように機能します。

132
Mike Müller

IMPORTANT

@マイクの答えは正しいが不正確すぎる。 Python 3.3+が__init__.pyファイルなしでパッケージを作成することを可能にする暗黙の名前空間パッケージをサポートするのは本当です。

ただし、これはEMPTY __init__.pyファイルにのみ適用されます。したがって、EMPTY __init__.pyファイルは不要になり、省略することができます。パッケージまたはそのモジュールまたはサブパッケージのいずれかがインポートされたときに特定の初期化スクリプトを実行したい場合でも、__init__.pyファイルが必要です。これがなんらかの意味で有用なのか疑問に思った場合に、__init__.pyファイルを使用してさらに初期化したい理由は、これは素晴らしい Stack Overflow answer です。

ディレクトリ構造の例:

  parent_package/
     __init__.py            <- EMPTY, NOT NECESSARY in Python 3.3+
     child_package/
          __init__.py       <- STILL REQUIRED if you want to run an initialization script
          child1.py
          child2.py
          child3.py

parent_package/child_package/__init__.py

print("from parent")

EXAMPLES

以下の例は、child_packageまたはそのモジュールの1つがインポートされたときの初期化スクリプトの実行方法を示しています。

例1

from parent_package import child_package  # prints "from parent"

例2

from parent_package.child_package import child1  # prints "from parent"
79
AndreasLukas

もしあなたがsetup.pyを持っていて、find_packages()を使っているなら、パッケージが自動的に見つかるようにするためにすべてのディレクトリに__init__.pyを持つことが必要です。

パッケージは__init__.pyファイルを含む場合にのみ認識されます

ドキュメント

0
trthhrtz

暗黙の名前空間パッケージ を使いたい場合に限り、__init__.pyを省略するべきであると私は言うでしょう。それが何を意味するのかわからない場合は、おそらくそれを望んでいないので、Python 3でも__init__.pyを使い続けるべきです。

0
Mi-La