Pregunta

Me estoy tomando un vistazo a cómo el modelo de sistema en django funciona y me di cuenta de algo que no entiendo.

Yo sé que usted cree un vacío __init__.py archivo para especificar que el directorio actual es un paquete.Y que se puede establecer alguna variable en __init__.py para que la importación * funciona correctamente.

Pero django añade un montón de ...importación ...declaraciones y define un grupo de clases en __init__.py.Por qué?No esta que acabo de hacer que las cosas se ven sucios?Hay una razón por la que requiere este código en __init__.py?

¿Fue útil?

Solución

Todas las importaciones en __init__.py están disponibles cuando se importa el paquete (directorio) que lo contiene.

Ejemplo:

./dir/__init__.py:

import something

./test.py:

import dir
# can now use dir.something

EDITAR:se olvidó de mencionar, el código de __init__.py se ejecuta la primera vez que la importación de cualquier módulo de directorio.Así que es normalmente un buen lugar para poner cualquier paquete de nivel de código de inicialización.

EDIT2:dgrant señaló una posible confusión en mi ejemplo.En __init__.py import something puede importar cualquier módulo, no es necesario en el paquete.Por ejemplo, se puede reemplazar con import datetime, a continuación, en nuestro nivel superior test.py ambos de estos snippets de trabajo:

import dir
print dir.datetime.datetime.now()

y

import dir.some_module_in_dir
print dir.datetime.datetime.now()

La parte inferior de la línea es:todos los nombres asignados en __init__.py, sean importados módulos, funciones o clases, están automáticamente disponibles en el paquete de espacio de nombres cada vez que importar el paquete o un módulo en el paquete.

Otros consejos

Es sólo una preferencia personal, y tiene que ver con el diseño de los módulos de python.

Digamos que usted tiene un módulo llamado erikutils.Hay dos formas en que puede ser un módulo, usted tiene un archivo llamado erikutils.py en su sys.path o usted tiene un directorio llamado erikutils en su sys.path con un vacío __init__.py el archivo dentro de ella.Entonces digamos que usted tiene un montón de módulos llamados fileutils, procutils, parseutils y desea que los sub-módulos de bajo erikutils.Así se hacen algunos .py archivos llamados fileutils.py, procutils.py, y parseutils.py:

erikutils
  __init__.py
  fileutils.py
  procutils.py
  parseutils.py

Tal vez usted tiene un par de funciones que simplemente no pertenecen a la fileutils, procutils, o parseutils los módulos.Y digamos que usted no se siente como la creación de un nuevo módulo llamado miscutils.Y, le gustaría ser capaz de llamar a la función así:

erikutils.foo()
erikutils.bar()

en lugar de hacer

erikutils.miscutils.foo()
erikutils.miscutils.bar()

Esto debido a que el erikutils el módulo es un directorio, un archivo, tenemos que definir sus funciones dentro de la __init__.py archivo.

En django, el mejor ejemplo que se me ocurre es django.db.models.fields.TODAS las django *Campo de clases se definen en el __init__.py en el archivo de django/db/modelos/campos directorio.Supongo que lo hicieron porque no querían meter todo en un hipotético django/db/models/fields.py el modelo, de modo que se separan de ella en un par de submódulos (related.py, files.py, por ejemplo) y se han pegado los hechos *las definiciones de Campo en los campos propio módulo (por lo tanto, __init__.py).

El uso de la __init__.py de archivo le permite hacer que el conjunto interno de la estructura invisible desde el exterior.Si los cambios en la estructura interna (por ejemplo,porque dividir una grasa módulo en dos) sólo tienes que ajustar el __init__.py archivo, pero no el código que depende del paquete.También puede hacer que las piezas de su paquete invisible, por ejemplo,si no está listo para el uso general.

Tenga en cuenta que puede utilizar la del comando, por lo que un típico __init__.py puede tener este aspecto:

from somemodule import some_function1, some_function2, SomeObject

del somemodule

Ahora bien, si usted decide dividir somemodule el nuevo __init__.py podría ser:

from somemodule1 import some_function1, some_function2
from somemodule2 import SomeObject

del somemodule1
del somemodule2

Desde el exterior, el paquete todavía se ve exactamente como antes.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top