¿Cómo escribo archivos de paquete __init__.py buenos/correctos?

Resuelto Marten Bauer asked hace 14 años • 3 respuestas

Mi paquete tiene la siguiente estructura:

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

No estoy seguro de cómo __init__.pyse deben escribir correctamente los archivos.
El __init__.py #1aspecto es:

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

Pero, ¿cómo debería __init__.py #2ser, por ejemplo? El mio es:

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

¿ Cuándo se debe __all__utilizar?

Marten Bauer avatar Dec 22 '09 13:12 Marten Bauer
Aceptado

__all__es muy bueno: ayuda a guiar las declaraciones de importación sin importar módulos automáticamente http://docs.python.org/tutorial/modules.html#importing-from-a-package

usando __all__y import *es redundante, solo __all__es necesario

Creo que una de las razones más poderosas para utilizarlo import *en la __init__.pyimportación de paquetes es poder refactorizar un script que se ha convertido en múltiples scripts sin romper una aplicación existente. Pero si estás diseñando un paquete desde el principio. Creo que es mejor dejar __init__.pylos archivos vacíos.

Por ejemplo:

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

luego la aplicación crece y ahora es una carpeta completa

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

entonces el script de inicio puede decir

__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

para que un script escrito para hacer lo siguiente no se rompa durante el cambio:

from foo import fooFactory, tallFoo, shortFoo
Fire Crow avatar Dec 22 '2009 17:12 Fire Crow

Mis propios __init__.pyarchivos están vacíos la mayoría de las veces. En particular, nunca tengo un from blah import *as parte de __init__.py: si "importar el paquete" significa definir todo tipo de clases, funciones, etc. directamente como parte del paquete, entonces copiaría léxicamente el contenido de blah.pyen el paquete __init__.pyy lo eliminaría blah.py( la multiplicación de archivos fuente no sirve de nada aquí).

Si insiste en respaldar los import *modismos (eek), entonces usarlos __all__(con una lista de nombres tan minúscula como pueda) puede ayudar a controlar los daños. En general, los espacios de nombres y las importaciones explícitas son cosas buenas , y recomiendo encarecidamente reconsiderar cualquier enfoque basado en omitir sistemáticamente uno o ambos conceptos.-)

Alex Martelli avatar Dec 22 '2009 06:12 Alex Martelli

Deberías __init__.pytener una cadena de documentación .

Aunque toda la funcionalidad se implementa en módulos y subpaquetes, la cadena de documentación de su paquete es el lugar para documentar por dónde empezar. Por ejemplo, considere el paquete Pythonemail . La documentación del paquete es una introducción que describe el propósito, los antecedentes y cómo funcionan juntos los distintos componentes del paquete. Si genera automáticamente documentación a partir de cadenas de documentos usando sphinx u otro paquete, la cadena de documentos del paquete es exactamente el lugar correcto para describir dicha introducción.

Para cualquier otro contenido, consulte las excelentes respuestas de firecrow y Alex Martelli .

gerrit avatar Jan 14 '2019 18:01 gerrit