¿Cómo escribo archivos de paquete __init__.py buenos/correctos?
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__.py
se deben escribir correctamente los archivos.
El __init__.py #1
aspecto es:
__all__ = ['mapper', 'vehicle']
import mapper
import vehicle
Pero, ¿cómo debería __init__.py #2
ser, por ejemplo? El mio es:
__all__ = ['basemapper', 'lxml']
from basemaper import *
import lxml
¿ Cuándo se debe __all__
utilizar?
__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__.py
importació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__.py
los 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
Mis propios __init__.py
archivos 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.py
en el paquete __init__.py
y 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.-)
Deberías __init__.py
tener 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 .