Importación del módulo Python: ¿por qué los componentes solo están disponibles cuando se importan explícitamente?

Recientemente instalé la versión scikit-image 0.11.3. Estoy usando python 2.7.10. Cuando importo el módulo completo no puedo acceder al módulo io.

import skimage img = skimage.io.imread(path_) 

Da error:

 AttributeError: 'module' object has no attribute 'io' 

Sin embargo, el siguiente no error.

 from skimage import io img = io.imread(path_) 

Pregunta: ¿Por qué?

Respuesta rápida: IO es un submódulo. Los submódulos deben importarse desde el módulo principal de forma explícita.

Respuesta larga: de la sección 5.4.2 de los documentos de python:

Cuando se carga un submódulo utilizando cualquier mecanismo (por ejemplo, las API de importación, las sentencias de importación o importación, o la importación integrada) se coloca un enlace en el espacio de nombres del módulo principal al objeto de submódulo. Por ejemplo, si el paquete de correo no deseado tiene un foo de submódulo, después de importar spam.foo, el correo no deseado tendrá un atributo foo que está vinculado al submódulo. Supongamos que tiene la siguiente estructura de directorios:

 spam/ __init__.py foo.py bar.py 

y spam / init .py tiene las siguientes líneas:

 from .foo import Foo from .bar import Bar 

luego, al ejecutar lo siguiente se coloca un enlace de nombre a foo y bar en el módulo de spam:

 >>> >>> import spam >>> spam.foo  >>> spam.bar  

Dadas las reglas de enlace de nombres familiares de Python, esto puede parecer sorprendente, pero en realidad es una característica fundamental del sistema de importación. Lo invariable es que si tiene sys.modules [‘spam’] y sys.modules [‘spam.foo’] (como lo haría después de la importación anterior), este último debe aparecer como el atributo foo del primero.

Es simplemente la forma en que Python maneja los módulos.

Una razón es que haría que la importación de un módulo fuera muy lenta si cpython necesitara buscar submódulos, importarlos todos y luego importar todos sus submódulos.

La otra razón es “mejor ser explícito que implícito”. ¿Por qué Python debe importar todo lo posible cuando solo necesita una pequeña fracción de un paquete con una compleja jerarquía de módulos?

En lugar de from skimage import io también puede escribir

 import skimage.io 

luego se encontrará skimage.io.imread.