Importación relativa absoluta o explícita del módulo Python

Me pregunto cuál es la forma preferida de importar paquetes en una aplicación Python. Tengo una estructura de paquete como esta:

project.app1.models project.app1.views project.app2.models 

project.app1.views importa project.app1.models y project.app2.models . Hay dos maneras de hacer esto que vienen a la mente.

Con importaciones absolutas:

 import AA import ABB 

o con importaciones relativas explícitas, como se introdujo en Python 2.5 con PEP 328 :

 # explicit relative import ..A import .B 

¿Cuál es la forma más pythonica de hacer esto?

Importaciones absolutas. De la PEP 8:

Las importaciones relativas para las importaciones dentro del paquete son altamente desalentadas. Utilice siempre la ruta del paquete absoluto para todas las importaciones. Incluso ahora que PEP 328 [7] está completamente implementado en Python 2.5, se desalienta activamente su estilo de importaciones relativas explícitas; Las importaciones absolutas son más portátiles y, por lo general, más legibles.

Las importaciones relativas explícitas son una buena característica del lenguaje (supongo), pero no son tan explícitas como las importaciones absolutas. La forma más legible es:

 import AA import ABB 

especialmente si importas varios espacios de nombres diferentes. Si observas algunos proyectos / tutoriales bien escritos que incluyen importaciones desde paquetes, generalmente siguen este estilo.

Las pocas pulsaciones adicionales que tome para ser más explícitas ahorrarán a otros (y quizás a usted) un montón de tiempo en el futuro cuando intenten descubrir su espacio de nombres (especialmente si migra a 3.x, en el cual parte del paquete los nombres han cambiado).

Las importaciones relativas de Python ya no están fuertemente desalentadas, pero en ese caso se sugiere el uso de absolute_import.

Por favor, vea esta discusión citando al propio Guido:

“¿No es esto en su mayoría histórico? Hasta que se implementó la nueva syntax de importación relativa hubo varios problemas con las importaciones relativas. La solución a corto plazo fue recomendar que no se usaran. La solución a largo plazo fue implementar una syntax inequívoca. Ahora es hora de retirar la anti-recomendación. Por supuesto, sin pasar por la borda, todavía encuentro un gusto adquirido, pero tienen su lugar “.

El OP vincula correctamente el PEP 328 que dice:

Se presentaron varios casos de uso, el más importante de los cuales es poder reorganizar la estructura de paquetes grandes sin tener que editar subpaquetes. Además, un módulo dentro de un paquete no puede importarse fácilmente sin importaciones relativas.

También vea la pregunta casi duplicada ¿ Cuándo o por qué usar las importaciones relativas en Python?

Por supuesto que sigue siendo una cuestión de gusto. Si bien es más fácil mover el código con importaciones relativas, eso también podría romper cosas inesperadamente; y cambiar el nombre de las importaciones no es tan difícil.

Para forzar el nuevo comportamiento del uso de PEP 328:

 from __future__ import absolute_import 

En este caso, la importación relativa implícita ya no será posible (por ejemplo, import localfile ya no funcionará, solo from . import localfile ). Para un comportamiento de prueba limpio y futuro, se recomienda el uso de absolute_import.

Una advertencia importante es que debido a PEP 338 y PEP 366 , las importaciones relativas requieren que el archivo python se importe como un módulo; no puede ejecutar un archivo.py que tenga una importación relativa o obtendrá un ValueError: Attempted relative import in non-package

Esta limitación debe tenerse en cuenta al evaluar el mejor enfoque. Guido está en contra de ejecutar scripts desde un módulo en cualquier caso:

Estoy -1 en esto y en cualquier otra propuesta de twiddlings de la maquinaria __main__. El único caso de uso parece estar ejecutando scripts que viven dentro del directorio de un módulo, lo que siempre he visto como un antipatrón. Para hacerme cambiar de opinión, tendrías que convencerme de que no lo es.

Las discusiones exhaustivas sobre el tema se pueden encontrar en SO; re. Python 3 esto es bastante completo:

  • Importaciones relativas en Python 3

Las importaciones relativas no solo lo dejan libre para cambiar el nombre de su paquete más tarde sin cambiar docenas de importaciones internas, sino que también he tenido éxito en resolver ciertos problemas relacionados con importaciones circulares o paquetes de espacio de nombres, ya que no envían Python “de vuelta al arriba “para comenzar de nuevo la búsqueda del siguiente módulo desde el espacio de nombres de nivel superior.