2009-05-22 12 views
10

¿Cómo configuro las importaciones de módulos para que cada módulo pueda acceder a los objetos de todos los demás?Importación correcta de módulos en Python

Tengo una aplicación de Python de tamaño medio con archivos de módulos en varios subdirectorios. He creado módulos que anexan estos subdirectorios al sys.path e importan un grupo de módulos, usando import thisModule as tm. Los objetos del módulo se mencionan con esa calificación. Luego importo ese módulo a los demás con from moduleImports import *. El código es descuidado en este momento y tiene varias de estas cosas, que a menudo son duplicativas.

Primero, la aplicación está fallando porque algunas referencias de módulo no están asignadas. Este mismo código se ejecuta cuando se prueba la unidad.

En segundo lugar, me preocupa que esté causando un problema con las importaciones de módulos recursivos. La importación de moduleImports importa thisModule, que importa moduleImports. . . .

¿Cuál es la forma correcta de hacerlo?

+0

No sé si esto responde directamente a su pregunta, pero [pregunté sobre la importación hace unos días] (http://stackoverflow.com/questions/860672/lay-out-import-pathing-in-python- recto y simple). Encontré las respuestas muy útiles. –

Respuesta

21

"Tengo una aplicación de Python de tamaño medio con archivos de módulos en varios subdirectorios."

Bueno. Asegúrese completamente de que cada directorio incluya un archivo __init__.py, de modo que sea un paquete.

"He creado módulos que Anexar estos subdirectorios a sys.path"

Bad. Use PYTHONPATH o instale toda la estructura Lib/site-packages. No actualice sys.path dinámicamente. Es algo malo Difícil de administrar y mantener.

"importa un grupo de módulos, usando import thisModule as tm."

No tiene sentido. Tal vez tenga un import thisModule as tm para cada módulo en su estructura. Esta es una práctica estándar típica: importe solo los módulos que necesita, no otros.

"Me continuación, importe ese módulo en los otros con from moduleImports import *"

Bad. No mantas importar un montón de cosas al azar.

Cada módulo debe tener una lista larga de las cosas específicas que necesita.

import this 
import that 
import package.module 

Lista explícita. Sin magia Sin cambio dinámico a sys.path.

Mi proyecto actual tiene 100 de módulos, más o menos una docena de paquetes. Cada módulo importa exactamente lo que necesita. Sin magia

+3

Envolviendo en una oración: "explícito es mejor que implícito". –

3

No obtendrá recursión en las importaciones porque Python guarda en caché cada módulo y no volverá a cargar uno que ya tiene.

+1

importación circular realmente puede suceder, p. supongamos que b define una función que usa y ambas se importan entre sí. http://www.copypastecode.com/codes/view/5193 –

+0

@Anurag Uniyal: ¿lo has probado realmente? import realiza un seguimiento de lo que importa, por lo que no existe garantía de que incluso ese código cause carga recursiva. – SpliFF

+0

Ocurre No recuerdo los detalles exactos ahora, pero tiene algo que ver con el mismo módulo importado dos veces como principal y luego como módulo –

6

algunos indicadores

  1. Ya se separaron funcionalidad en diferentes módulos. Si se hace correctamente la mayoría de las veces se no caigan en la importación circular problemas (por ejemplo, si un módulo depende en B y B en una se puede hacer una tercera módulo C para eliminar dicha dependencia circular ). Como último recurso, en una importación b pero en una importación b en el punto donde se necesita a, p. dentro de la función .

  2. Una vez que la funcionalidad es adecuada en módulos agruparlas en paquetes bajo un subdirectorio y añadir un archivo __init__.py a él para que pueda importar el paquete . Guarde dichos paquetes en una carpeta , p. lib y entonces o bien se suman a sys.path o conjunto env PYTHONPATH variables

  3. de importación de módulo * puede no ser buena idea. En su lugar, importe lo que sea necesario. Puede ser completamente calificado. Es no hace daño ser detallado. p.ej. desde pakageA.moduleB importar CoolClass.

+0

Nota de formato menor: Creo que quiere decir __init__.py (use los puntos para evitarlo) convirtiéndose en negrita.) –

+0

gracias, estos lenguajes de formato simples a veces se vuelven complejos de administrar –

+0

No entiendo lo que quiere decir con "funcionalidad dividida", o cómo un tercer módulo ayudaría a resolver la interdependencia entre dos módulos. – chernevik

4

La forma de hacerlo es evitar la magia. En otras palabras, si su módulo requiere algo de otro módulo, debe importarlo explícitamente. No debe confiar en que las cosas se importen automáticamente.

Como lo tiene el Zen de Python (import this), explícito es mejor que implícito.

Cuestiones relacionadas