2009-12-16 15 views
12

Tengo dos preguntas relacionadas de 'importación' de Python. Se pueden probar fácilmente, pero quiero respuestas que estén definidas por el lenguaje y no específicas de la implementación, y también me interesan el estilo/la convención, por lo tanto, en este caso, lo estoy preguntando.Mecánica de importación de Python

1)

Si el módulo de importaciones Módulo A B, y el módulo de módulo de importaciones B C, pueden codificar en el módulo A módulo de referencia C sin una importación explícita? Si es así, ¿estoy en lo cierto al suponer que esta es una mala práctica?

2)

Si importo A.B.C módulo, hace que los módulos de importación A y A.B así? Si es así, ¿es mejor convenir explícitamente que import A; import A.B; import A.B.C?

+0

"definido por el lenguaje y no específico de la implementación" ¿Está diciendo que las implementaciones de Python son de alguna manera diferentes? ¿De qué diferencias específicas conoce? AFAIK no hay ninguno. –

+0

Quizás no haya ninguna diferencia, pero cualquier cosa no definida por la especificación depende de la implementación. Los documentos de Python están llenos de advertencias sobre los detalles de implementación de CPython que podrían no aplicarse en otras implementaciones. –

Respuesta

12

Lo primero que debe saber es que el lenguaje Python NO es un estándar ISO. Esto es bastante diferente de C/C++, y significa que no hay una forma "adecuada" de definir un comportamiento del lenguaje: CPython podría hacer algo simplemente porque estaba codificado de esa manera, y Jython podría hacerlo al revés.

acerca de sus preguntas, recuerde que "importar" un módulo es una operación de dos partes: primero, el módulo se carga, si nunca lo ha estado, p. si no estaba disponible en sys.modules, entonces un nombre está vinculado a ese módulo en el espacio de nombres local.

por lo tanto:

1) Sí, se puede hacer referencia a lo que quieras de un módulo, proporcionando el espacio de nombres adecuado, por ejemplo, vas a tener que hacer algo como

BCname = "algo"

Y creo que esto es muy rara vez se hace en los programas de Python y podría ser considerada una mala práctica, ya que obliga a una "transitiva dep" - si algunos la implementación del módulo B se refactoriza y ya no depende de C, debe continuar ofreciendo el módulo C solo para satisfacer las deficiencias A.

Por supuesto, establecer __ todos __ puede evitar esto, y una buena práctica puede ser poner __ todos __ en todos sus módulos y exportar solo los símbolos que desea que sean realmente públicos.

2) Sí y no. Haciendo

import a.b.c.d 

realiza la primera fase de importación (carga) en todos los módulos, pero el segundo sólo en una (y, de forma recursiva, en b con respecto a c, etc), pero todos los módulos de la cadena debe ser referenciado por el espacio de nombres completo; después de una importación tal, que puede hacer

a.something 
a.b.something 
a.b.c.something 

pero no se puede hacer

c.something 
b.something 

he de reconocer que tipo de uso es bastante raro, así; Por lo general, prefiero el modo de importación de "desde el módulo de importación" y, en general, solo pides lo que necesitas; dicho agrupamiento no es común en las bibliotecas ni su uso es tan común.

Muchas veces hay "paquetes externos", que solo se usan para organización, que contienen módulos con clases. Es muy probable que a, b, c de arriba sean solo paquetes, yd es un módulo que realmente contiene clases, funciones y otros objetos.Así que el uso correcto sería:

from a.b.c.d import name1, name2, name3 

Espero que esto satites tu curiosidad.

+0

¡Gracias por la respuesta detallada! –

+0

Si bien no es ISO, existe una referencia de lenguaje Python que define el comportamiento "adecuado", incluidas las importaciones: http://docs.python.org/reference/simple_stmts.html#the-import-statement La referencia de idioma señala Detalles de implementación de CPython, pero pretende ser una especificación genérica del lenguaje, de modo que no depende de la implementación. –

11

Alan ha dado una gran respuesta, pero quería agregar que para su pregunta 1 depende de lo que quiere decir con 'importaciones'.

Si usa la sintaxis from C import x, entonces x estará disponible en el espacio de nombres de B. Si en A usted hace import B, tendrá tiene acceso a x de A como B.x.

No es tanto una mala práctica como potencialmente confusa, y hará que la depuración sea más difícil ya que no necesariamente sabrá de dónde vienen los objetos.

+0

Esa es una aclaración útil, gracias. He estado pensando en 'importar' como similar a las importaciones de paquetes de estilo Java, pero es evidente que la similitud es meramente superficial. –

+0

Si es confuso, ¿no es motivo suficiente para llamarlo mala práctica? Debería ser obvio qué código hace solo al leerlo en mi humilde opinión. – jjpe

Cuestiones relacionadas