Как мне написать хорошие / правильные файлы пакета __init__.py - PullRequest
172 голосов
/ 22 декабря 2009

Моя посылка имеет следующую структуру:

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__?

Ответы [ 3 ]

135 голосов
/ 22 декабря 2009

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

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

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

тогда скрипт инициализации может сказать

__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
106 голосов
/ 22 декабря 2009

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

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

1 голос
/ 14 января 2019

Ваш __init__.py должен иметь строку документации .

Хотя вся функциональность реализована в модулях и подпакетах, строка документации вашего пакета - это то место, где нужно документировать, с чего начать. Например, рассмотрим пакет python email . Документация пакета представляет собой введение, описывающее цель, фон и то, как различные компоненты в пакете работают вместе. Если вы автоматически генерируете документацию из строк документации, используя sphinx или другой пакет, пакет документации doc является именно тем местом, где можно описать такое введение.

Для любого другого контента, посмотрите отличные ответы firecrow и Alex Martelli .

...