2012-09-20 10 views
5

Uso __init__.py para ejecutar comprobaciones cuando lo hago from myprojects.something import blabla.uso de __init__.py

Hoy comencé a usar pyzmq y quería ver lo que sucede detrás de escena. Así que busqué el código en github y encontré (para mí) algún extraño uso de __init__.py que no puedo explicar.

Por ejemplo zmq/core/__init__.py. ¿Cuál es el punto de agregar en zmq.core.__all__ el valor __all__ de zmq.core.constants, zmq.core.error, zmq.core.message, etc.?

En zmq/__init__.py veo al final

__all__ = ['get_includes'] + core.__all__ 

donde get_includes es una función que básicamente devuelve una lista con el directorio del módulo y el directorio de utilidades en el directorio padre.

¿Cuál es el punto de eso? ¿Qué ha logrado __init.py__ haciendo eso?

Respuesta

11

La __all__ es para cuando alguien hace from module import * como se documentó here.

La única solución es que el autor del paquete proporcione un índice explícito del paquete. La declaración de importación utiliza la siguiente convención : si el código __init__.py de un paquete define una lista llamada __all__, se toma como la lista de nombres de módulos que se deben importar cuando se encuentra la importación del paquete *. Depende del autor del paquete mantener esta lista actualizada cuando se lanza una nueva versión del paquete . Los autores del paquete también pueden decidir no admitir el , si no ven un uso para importar * desde su paquete. Para ejemplo, el archivo podría contener la sounds/effects/__init__.py siguiente código:

__all__ = ["echo", "surround", "reverse"] 

Esto significaría que habría from sound.effects import * importar los tres submódulos del mismo nombre del paquete de sonido.

Un uso para __all__ es una herramienta para los constructores de paquetes para que puedan estructurar su paquete en una manera que funcione para ellos, mientras que por lo que es conveniente para los usuarios. Específicamente en el caso de pyzmq, que le permite escribir código como:

import zmq 
print zmq.zmq_version() 

En lugar de tener que utilizar todo el nombre del módulo de puntos:

print zmq.core.version.zmq_version() 

El paquete diseñadores de pyzmq están utilizando __all__ para promover elementos del espacio de nombres de los módulos anidados hasta el nivel superior de su espacio de nombres para que el usuario no se sienta molesto por la estructura de su paquete.

+0

He leído esta parte de la documentación antes de preguntar aquí. Pero esto aún no responde mi pregunta. Tal vez debería preguntar de otra manera: pensé que la razón para usar 'from bla import ble' era que usted tenía control sobre su espacio de nombres, lo que significa que usted decide qué símbolos agrega a su nombre. – Pablo

+0

Como en contraste con C, donde usar '# include' podría causar una colisión con las funciones, variables, etc. ya definidas, solo debería importar los símbolos que realmente necesita. Aunque leí en algún lugar de la documentación de Python que usar 'from bla import *' no era un buen hábito. Si es así, ¿por qué molestarse en definir '__ all__' en absoluto? ¿Y cómo se evalúa '__all__ = ['get_includes'] + core .__ all__' cuando se hace' import * '? – Pablo

+1

de la importación de bla * no es una buena costumbre, pero hay algunos módulos para los que generalmente es seguro. Lo hago rutinariamente desde la importación de matemáticas *. La documentación de esos módulos a menudo señala que están diseñados para ser utilizados de esa manera y admiten detalles tales como __all__ para hacerlo un poco más fácil. Pero a partir de x import * aún queda algo por usar con precaución y solo con paquetes donde se sabe que no causará ningún problema. – TimothyAWiseman

Cuestiones relacionadas