Python 3.3 以降のパッケージでは __init__.py は必要ありませんか? 質問する

Python 3.3 以降のパッケージでは __init__.py は必要ありませんか? 質問する

私は 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>

同様に、 の のhomeスーパーフォルダは次のようになります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 パスがフォルダーを指しているときにインポートできるようにするには、__init__.py両方にファイル (空のファイルでも機能します)が必要であると考えていました。abmodule.pyPlayground

これは 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なく動作します。

ベストアンサー1

概要

@Mike さんの回答は正しいですが、あまりに不正確です。Python 3.3 以降では、ファイルなしでパッケージを作成できる暗黙的な名前空間パッケージがサポートされているのは事実です。これは、ファイル (空または空でない)を持つ通常のパッケージとは対照的に、名前空間パッケージ__init__.pyと呼ばれます。__init__.py

ただし、名前空間パッケージの作成は、必要な場合にのみ行う必要があります。ほとんどのユースケースと開発者にはこれは当てはまらないため、空の__init__.pyファイルを使用するようにしてください。

名前空間パッケージの使用例

2 種類の Python パッケージの違いを示すために、次の例を見てみましょう。

google_pubsub/              <- Package 1
    google/                 <- Namespace package (there is no __init__.py)
        cloud/              <- Namespace package (there is no __init__.py)
            pubsub/         <- Regular package (with __init__.py)
                __init__.py <- Required to make the package a regular package
                foo.py

google_storage/             <- Package 2
    google/                 <- Namespace package (there is no __init__.py)
        cloud/              <- Namespace package (there is no __init__.py)
            storage/        <- Regular package (with __init__.py)
                __init__.py <- Required to make the package a regular package
                bar.py

google_pubsubと はgoogle_storage別々のパッケージですが、同じ名前空間を共有しますgoogle/cloud。同じ名前空間を共有するには、共通パスの各ディレクトリを名前空間パッケージ、つまりgoogle/と にする必要がありますcloud/これは、名前空間パッケージを作成する唯一のユースケースであるはずです。それ以外の場合、名前空間パッケージを作成する必要はありません。

両方のディレクトリを名前空間パッケージとして解釈できるように、およびディレクトリ__init__pyにファイルが存在しないことが重要です。googlegoogle/cloudsys.pathPython 3.3以降では、検索対象のパッケージ名と一致する名前を持つディレクトリは、そのパッケージに貢献するモジュールとサブパッケージとして認識されます。その結果、google_pubsubとの両方をインポートするとgoogle_storage、Python インタープリターはそれらを見つけることができます。

これは、すべてのパーツが同じディレクトリ階層に存在する自己完結型の通常のパッケージとは異なります。パッケージをインポートするときに、Pythonインタープリターがsys.pathファイルを含むサブディレクトリに遭遇する__init__.pyと、そのディレクトリの外側にある適切な名前のサブディレクトリをすべて探すのではなく、そのディレクトリのモジュールのみを含む単一のディレクトリパッケージを作成します。これは、名前空間を共有したくないパッケージにはまったく問題ありませんPython のインポート システムに潜む不注意な罠__init__.pyPython のインポートが通常パッケージと名前空間パッケージでどのように動作するか、またどのような罠に注意すべきかをより深く理解します。

まとめ

  • 名前空間パッケージ__init__.pyを作成する場合にのみ、ファイルをスキップします。異なる場所に異なるライブラリがあり、それぞれが親パッケージ、つまり名前空間パッケージにサブパッケージを提供する場合にのみ、名前空間パッケージを作成します。
  • __init__.py99% の場合、通常のパッケージを作成したいだけなので、ディレクトリに空のファイルを追加し続けます。また、やなどの Python ツールではmypy、コード構造を適切に解釈するためにpytest空のファイルが必要です__init__.py。注意して行わないと、奇妙なエラーが発生する可能性があります。

リソース

私の回答は、通常のパッケージ名前空間パッケージがどのように機能するかについて表面的な部分しか触れていないため、詳細については次のリソースを参照してください。

おすすめ記事