Как написать хороший/правильный пакет __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__ использовано?

Ответ 1

__all__ очень хорош - он помогает управлять инструкциями импорта без автоматического импорта модулей http://docs.python.org/tutorial/modules.html#importing-from-a-package

с использованием __all__ и import * является избыточным, требуется только __all__

Я думаю, что одна из самых веских причин использовать import * в __init__.py для импорта пакетов - это возможность реорганизовать script, который вырос на несколько сценариев, не нарушая существующее приложение. Но если вы разрабатываете пакет с самого начала. Я думаю, что лучше оставить файлы __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 script может сказать

__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

так что a script, написанный для выполнения следующего: во время изменения не прерывается:

from foo import fooFactory, tallFoo, shortFoo

Ответ 2

Мои собственные __init__.py файлы пустые чаще, чем нет. В частности, у меня никогда не было from blah import * как части __init__.py - если "импорт пакета" означает получение всех классов, функций и т.д., Определенных непосредственно как часть пакета, тогда я бы лексически скопировал содержимое blah.py в пакет __init__.py вместо этого и удалите blah.py (умножение исходных файлов здесь не подходит).

Если вы настаиваете на поддержке import * идиом (eek), то с помощью __all__ (с минимальным списком имен, которые вы можете привести в себя) может помочь контролировать повреждение. В общем, пространства имен и явный импорт - это хорошие вещи, и я настоятельно рекомендую пересмотреть любой подход, основанный на систематическом обходе обоих или обоих понятий! -)