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 se __init__.py
deben escribir correctamente los archivos.
El se __init__.py #1
parece a:
__all__ = ['mapper', 'vehicle']
import mapper
import vehicle
Pero, ¿cómo debería ser, por ejemplo __init__.py #2
? El mio es:
__all__ = ['basemapper', 'lxml']
from basemaper import *
import lxml
¿Cuándo se debe __all__
usar?
Respuestas:
__all__
es muy bueno: ayuda a guiar las declaraciones de importación sin importar automáticamente los módulos http://docs.python.org/tutorial/modules.html#importing-from-a-packageusando
__all__
yimport *
es redundante, solo__all__
es necesarioCreo que una de las razones más poderosas para usar
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á diseñando un paquete desde el principio. Creo que es mejor dejar los__init__.py
archivos vacíos.por ejemplo:
entonces la aplicación crece y ahora es una carpeta completa
entonces el guión de inicio puede decir
para que un script escrito para hacer lo siguiente no se rompa durante el cambio:
fuente
__all__
yimport *
es redundante",__all__
es usado por el consumidor del módulo, yfrom foo import *
es usado por el propio módulo para usar otros ...using __all__ and import * is redundant, only __all__ is needed
¿Cómo son esos redundantes? Ellos hacen cosas diferentes.Mis propios
__init__.py
archivos están vacíos la mayoría de las veces. En particular, nunca tengo unfrom blah import *
como parte de__init__.py
: si "importar el paquete" significa obtener todo tipo de clases, funciones, etc., definidas directamente como parte del paquete, entonces copiaría léxicamente el contenido delblah.py
paquete__init__.py
y lo eliminaríablah.py
( la multiplicación de los archivos fuente no sirve de nada aquí).Si insiste en apoyar las
import *
expresiones idiomáticas (eek), usar__all__
(con una lista de nombres tan minúscula como pueda tener) puede ayudar a controlar el daño. En general, los espacios de nombres y las importaciones explícitas son cosas buenas , ¡y sugiero que reconsidere cualquier enfoque basado en omitir sistemáticamente uno o ambos conceptos! -)fuente
import *
, debe aceptar incondicionalmente todo el marco en su totalidad, incluso las características que nunca usará. mantenerse__init__.py
vacío le brinda más oportunidades que solo semántica de todo o nada. pensar en retorcido.from mobilescouter import A, B
es solo una línea de código y no tienes un proyecto con 666 clases y cada una con su propio archivo, ¿verdad? Si tiene dos o másimport *
en su código, está llenando el espacio de nombres con basura potencial y rápidamente olvidará de dóndeA
viene. ¿Y si un paquete superior hace lo mismo? estás agarrando todos los subpaquetes y subpaquetes. Como dice el zen de Python, explícito es mejor que implícito.Su
__init__.py
debe 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 dónde comenzar. Por ejemplo, considere el paquete python
email
. La documentación del paquete es una introducción que describe el propósito, los antecedentes y cómo los diversos componentes dentro del paquete funcionan juntos. Si genera automáticamente documentación de cadenas de documentos utilizando sphinx u otro paquete, la cadena de documentos del paquete es exactamente el lugar adecuado para describir dicha introducción.Para cualquier otro contenido, vea las excelentes respuestas de firecrow y Alex Martelli .
fuente
__init__.py
para elemail
paquete sigue esta directriz? Veo una cadena de documentación de una sola línea que no hace mucho para explicar "cómo funcionan juntos los diversos componentes del paquete".