Estoy echando un vistazo a cómo funciona el sistema modelo en django y noté algo que no entiendo.
Sé que crea un __init__.pyarchivo vacío para especificar que el directorio actual es un paquete. Y que puede establecer alguna variable __init__.pypara que la importación * funcione correctamente.
Pero django agrega un montón de declaraciones from ... import ... y define un montón de clases en __init__.py. ¿Por qué? ¿No hace esto que las cosas se vean desordenadas? ¿Hay alguna razón por la que se requiera este código __init__.py?

__init__.pydjango 1.8. ¿Fue esto para una versión anterior? si es así, ¿qué versión?Respuestas:
Todas las importaciones en
__init__.pyestán disponibles cuando importa el paquete (directorio) que lo contiene.Ejemplo:
./dir/__init__.py:import something./test.py:import dir # can now use dir.somethingEDITAR: olvidé mencionar, el código se
__init__.pyejecuta la primera vez que importa cualquier módulo de ese directorio. Por lo tanto, normalmente es un buen lugar para colocar cualquier código de inicialización a nivel de paquete.EDIT2: dgrant señaló una posible confusión en mi ejemplo. En
__init__.pyimport somethingpuede importar cualquier módulo, no es necesario del paquete. Por ejemplo, podemos reemplazarlo conimport datetime, luego, en nuestro nivel superior,test.pyestos dos fragmentos funcionarán:import dir print dir.datetime.datetime.now()y
import dir.some_module_in_dir print dir.datetime.datetime.now()La conclusión es: todos los nombres asignados
__init__.py, ya sean módulos, funciones o clases importados, están disponibles automáticamente en el espacio de nombres del paquete cada vez que importa el paquete o un módulo en el paquete.fuente
__init__.py. Realmente no considero el código de inicialización de estas clases (pero tal vez me equivoque al respecto).__init__.pyimplícitamente. Al importar los módulos internos__init__.py, está creando importaciones cíclicas. El__init__.pyno se ejecutará por completo antes de uno de tales importaciones. Es más seguro mantenerlo__init__.pyvacío.__init__.pyarchivos. Si tuviera un archivodir/other.pyque tuviera algo comofrom datetime import datetime, también podría llamardir.other.datetime.now()o inclusofrom dir.other import datetime.En realidad, es solo una preferencia personal y tiene que ver con el diseño de sus módulos de Python.
Digamos que tiene un módulo llamado
erikutils. Hay dos formas en que puede ser un módulo, o tiene un archivo llamado erikutils.py en susys.patho tiene un directorio llamado erikutils en susys.pathcon un__init__.pyarchivo vacío dentro. Entonces digamos que usted tiene un montón de módulos llamadosfileutils,procutils,parseutilsy que desea que estén bajo submóduloserikutils. Entonces crea algunos archivos .py llamados fileutils.py , procutils.py y parseutils.py :Tal vez usted tiene algunas funciones que simplemente no tienen cabida en los
fileutils,procutilsoparseutilsmódulos. Y digamos que no tiene ganas de crear un nuevo módulo llamadomiscutils. Y, le gustaría poder llamar a la función así:en lugar de hacer
Entonces, debido a que el
erikutilsmódulo es un directorio, no un archivo, tenemos que definir sus funciones dentro del__init__.pyarchivo.En django, el mejor ejemplo en el que puedo pensar es
django.db.models.fields. TODAS las clases de django * Field se definen en el__init__.pyarchivo en el directorio django / db / models / fields . Supongo que hicieron esto porque no querían meter todo en un modelo hipotético de django / db / models / fields.py , por lo que lo dividieron en algunos submódulos ( related.py , files.py , por ejemplo) y pegaron las definiciones de * Field hechas en el módulo de campos en sí (por lo tanto,__init__.py).fuente
somethingpuede ser un módulo externo, dir. algo funcionará. Gracias por el comentario, editaré mi publicación para que quede más claro.El uso del
__init__.pyarchivo le permite hacer que la estructura interna del paquete sea invisible desde el exterior. Si la estructura interna cambia (por ejemplo, porque divide un módulo fat en dos) solo tiene que ajustar el__init__.pyarchivo, pero no el código que depende del paquete. También puede hacer que partes de su paquete sean invisibles, por ejemplo, si no están listas para uso general.Tenga en cuenta que puede usar el
delcomando, por lo que un típico__init__.pypuede verse así:from somemodule import some_function1, some_function2, SomeObject del somemoduleAhora bien, si decides dividir
somemoduleel nuevo__init__.pypodría ser:from somemodule1 import some_function1, some_function2 from somemodule2 import SomeObject del somemodule1 del somemodule2Desde el exterior, el paquete todavía se ve exactamente como antes.
fuente
import <pack>.somemodule1directamente. Solo puede importar desde<pack>objetos definidos o importados en sus__init__.pysubmódulos y no eliminados.