web-dev-qa-db-fra.com

Comment écrire des fichiers de package bon/correct __init__.py

Mon paquet a la structure suivante:

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
   ...

Je ne sais pas comment les fichiers __init__.py doivent être écrits correctement.
Le __init__.py #1 ressemble à:

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

Mais à quoi ressemblerait par exemple __init__.py #2? Le mien est:

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

Quand devrait-on utiliser __all__

171
Marten Bauer

__all__ est très bon - il aide à guider les instructions d'importation sans importer automatiquement les modules http://docs.python.org/tutorial/modules.html#importing-from-a-package

utiliser __all__ et import * est redondant, seul __all__ est nécessaire

Je pense que l’une des raisons les plus puissantes d’utiliser import * dans un __init__.py pour importer des packages est de pouvoir refactoriser un script qui a évolué en plusieurs scripts sans casser une application existante. Mais si vous concevez un package dès le début. Je pense qu'il est préférable de laisser les fichiers __init__.py vides.

par exemple:

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

alors l'application grandit et maintenant c'est un dossier entier

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

alors le script init peut dire

__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

afin qu'un script écrit pour faire ce qui suit ne soit pas interrompu pendant le changement:

from foo import fooFactory, tallFoo, shortFoo
131
Fire Crow

Mes propres fichiers __init__.py sont vides le plus souvent. En particulier, je n'ai jamais de from blah import * dans __init__.py - si "importer le paquet" signifie obtenir toutes sortes de classes, fonctions, etc. directement définies dans le paquet, je copierais lexicalement le contenu de blah.py dans le __init__.py du paquet. à la place, supprimez blah.py (la multiplication des fichiers sources n’a aucun effet ici).

Si vous insistez pour prendre en charge les idiomes import * (eek), utiliser __all__ (avec aussi minuscule une liste de noms que vous pouvez vous en procurer) peut aider à limiter les dégâts. En général, les espaces de noms et les importations explicites sont bonnes choses, et je suggère fortement de reconsidérer toute approche basée sur le contournement systématique de l'un ou des deux concepts! -)

105
Alex Martelli

Votre __init__.py devrait avoir un docstring.

Bien que toutes les fonctionnalités soient implémentées dans des modules et des sous-packages, votre documentation docstring est l'endroit où documenter par où commencer. Par exemple, considérons le package python email . La documentation du paquet est une introduction décrivant l'objectif, le contexte et la manière dont les divers composants du paquet fonctionnent ensemble. Si vous générez automatiquement de la documentation à partir de docstrings à l'aide de sphinx ou d'un autre package, le package docstring est exactement le bon endroit pour décrire une telle introduction.

Pour tout autre contenu, voir les excellentes réponses de Firecrow et Alex Martelli .

0
gerrit