2009-12-24 7 views
8

Básicamente tengo un subpaquete con el mismo nombre que un paquete de biblioteca estándar ("logging") y me gustaría poder importar de forma absoluta el estándar no Importe cómo lo ejecuto, pero esto falla cuando estoy en el paquete principal.Falló la importación absoluta en el subpaquete que sombrea un nombre de paquete stdlib

Parece realmente un error o un comportamiento no documentado del nuevo soporte de "importación absoluta" (nuevo a partir de Python 2.5). Intentó con 2.5 y 2.6.

diseño del paquete:

foo/ 
    __init__.py 
    logging/ 
     __init__.py 

En foo/__init__.py importamos nuestro propio registro de sub-paquete:

from __future__ import absolute_import 
from . import logging as rel_logging 
print 'top, relative:', rel_logging 

En foo/logging/__init__.py queremos importar el paquete stdlib logging:

from __future__ import absolute_import 
print 'sub, name:', __name__ 

import logging as abs_logging 
print 'sub, absolute:', abs_logging 

Nota : La carpeta que contiene foo se encuentra en sys.path.


Cuando se importan desde fuera/por encima de foo, la salida es como se esperaba:

c:\> python -c "import foo" 
sub, name: foo.logging 
sub, absolute: <module 'logging' from 'c:\python26\lib\logging\__init__.pyc'> 
top, relative: <module 'foo.logging' from 'foo\logging\__init__.pyc'> 

Así la importación absoluta en el subpaquete encuentra el paquete stdlib lo deseas.

Pero cuando estamos dentro de la carpeta foo, se comporta de manera diferente:

c:\foo>\python25\python -c "import foo" 
sub, name: foo.logging 
sub, name: logging 
sub, absolute: <module 'logging' from 'logging\__init__.pyc'> 
sub, absolute: <module 'logging' from 'logging\__init__.pyc'> 
top, relative: <module 'foo.logging' from 'c:\foo\logging\__init__.pyc'> 

La doble salida para "sub, el nombre" muestra que mi propia sub-paquete llamado "registro" es la importación de sí mismo una segunda vez, y no encuentra el paquete stdlib "logging" aunque "absolute_import" está habilitado.

El caso de uso es que me gustaría poder trabajar con este paquete, probarlo, etc., independientemente de cuál sea el directorio actual. Cambiar el nombre de "logging" a otra cosa sería una solución alternativa, pero no deseable, y en cualquier caso, este comportamiento no parece ajustarse a la descripción de cómo deberían funcionar las importaciones absolutas.

¿Alguna idea de qué está pasando, si esto es un error (mío o de Python), o si este comportamiento está de hecho implícito en alguna documentación?

Editar: la respuesta de gahooa muestra claramente cuál es el problema. Un crudo solución alternativa que demuestra que está se muestra aquí:

c:\foo>python -c "import sys; del sys.path[0]; import foo" 
sub, name: foo.logging 
sub, absolute: <module 'logging' from 'c:\python26\lib\logging\__init__.pyc'> 
top, relative: <module 'foo.logging' from 'c:\foo\logging\__init__.pyc'> 

Respuesta

10

sys.path[0] es por defecto '', que significa "directorio actual". Entonces, si está sentado en un directorio con logging en él, será elegido primero.

me encontré con esto recientemente, hasta que me di cuenta de que en realidad estaba sentado en ese directorio y que sys.path estaba recogiendo mi directorio actual PRIMERO, antes de buscar en la biblioteca estándar.

+0

Gracias. Me acababa de dar cuenta de lo mismo que pondere esto más durante el almuerzo.Supongo que es inevitable que esto suceda a menos que elimines deliberadamente sys.path [0] o muevas "hasta el final o algo así". Lo notaré en mi pregunta. –

Cuestiones relacionadas