web-dev-qa-db-ja.com

良い/正しいパッケージ__init__.pyファイルの書き方

私のパッケージの構造は次のとおりです。

mobilescouter/
    __init__.py #1
    mapper/
        __init__.py  #2
        lxml/
            __init__.py #3
            vehiclemapper.py
            vehiclefeaturemapper.py
            vehiclefeaturesetmapper.py
        ...
        basemapper.py
   vehicle/
        __init__.py #4
        vehicle.py
        vehiclefeature.py
        vehiclefeaturemapper.py
   ...

__init__.pyファイルがどのように正しく書き込まれるべきかわかりません。
__init__.py #1は次のようになります。

__all__ = ['mapper', 'vehicle']
import mapper
import vehicle

しかし、たとえば__init__.py #2はどのように見えるべきでしょうか?私は:

__all__ = ['basemapper', 'lxml']
from basemaper import *
import lxml

いつ__all__を使用する必要がありますか?

173
Marten Bauer

__all__は非常に優れています-モジュールを自動的にインポートせずにインポートステートメントをガイドするのに役立ちます http://docs.python.org/tutorial/modules.html#importing-from-a-package

__all__import *の使用は冗長であり、__all__のみが必要です

import *__init__.pyを使用してパッケージをインポートする最も強力な理由の1つは、既存のアプリケーションを中断することなく、複数のスクリプトに成長したスクリプトをリファクタリングできるからだと思います。ただし、パッケージを最初から設計している場合。 __init__.pyファイルは空のままにしておくのが最善だと思います。

例えば:

foo.py - contains classes related to foo such as fooFactory, tallFoo, shortFoo

その後、アプリが大きくなり、フォルダー全体になります

foo/
    __init__.py
    foofactories.py
    tallFoos.py
    shortfoos.py
    mediumfoos.py
    santaslittlehelperfoo.py
    superawsomefoo.py
    anotherfoo.py

その後、initスクリプトは言うことができます

__all__ = ['foofactories', 'tallFoos', 'shortfoos', 'medumfoos',
           'santaslittlehelperfoo', 'superawsomefoo', 'anotherfoo']
# deprecated to keep older scripts who import this from breaking
from foo.foofactories import fooFactory
from foo.tallfoos import tallFoo
from foo.shortfoos import shortFoo

次のことを行うために書かれたスクリプトが変更中に壊れないようにするためです。

from foo import fooFactory, tallFoo, shortFoo
139
Fire Crow

私自身の__init__.pyファイルは多くの場合空です。特に、from blah import *の一部として__init__.pyを持っていません-「パッケージのインポート」とは、パッケージの一部としてあらゆる種類のクラス、関数などを直接定義することを意味する場合、字句的にコピーします代わりにblah.pyの内容をパッケージの__init__.pyに追加し、blah.pyを削除します(ソースファイルの乗算はここでは役に立ちません)。

import *イディオム(eek)のサポートを主張する場合は、__all__を使用すると(名前のリストを最小限に抑えて)、被害管理に役立つ場合があります。一般に、名前空間と明示的なインポートはgoodであり、どちらかまたは両方の概念を体系的にバイパスすることに基づいてアプローチを再検討することを強くお勧めします!-)

108
Alex Martelli

__init__.pyにはdocstringが必要です。

すべての機能はモジュールとサブパッケージに実装されていますが、パッケージのdocstringは開始点を文書化する場所です。たとえば、 python email package を考えてください。パッケージドキュメントは、目的、背景、およびパッケージ内のさまざまなコンポーネントがどのように連携するかを説明する概要です。 sphinxまたは別のパッケージを使用してdocstringsからドキュメントを自動的に生成する場合、パッケージdocstringはそのような紹介を説明するのにぴったりの場所です。

その他のコンテンツについては、 firecrow および Alex Martelli による優れた回答をご覧ください。

1
gerrit