2009-08-11 13 views
5

Tengo problemas con la sustitución de mis propios módulos incorporados en Python (específicamente el módulo de registro). Aquí está mi diseño del proyecto:Otro problema de importación absoluta

run.py 
package/ 
     __init__.py 
     logging/ 
       __init__.py 
     ... 

run.py

from package import main 

main() 

paquete/__ init__.py

from __future__ import absolute_import 
import logging 
import logging.config 

def main(): 
    logging.config.fileConfig(...) 

paquete/registro/__ init__.py

class Logging(object): 
    pass 

Como se encuentra en este momento, el código anterior funciona. Tan pronto como intento importar la clase de registro de package.logging así:

from __future__ import absolute_import 

import logging 
import logging.config 
from package.logging import Logging 

def main(): 
    logging.config.fileConfig(...) 

consigo un error:

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

He leído las notas de la versión PEP 328 y encontré importaciones en términos absolutos a ser bastante sencillo. Lamentablemente, no he sido capaz de resolver esto.

¿Qué me falta aquí?

Respuesta

1

Se puede utilizar para forzar relative imports donde Python busca los primeros módulos:

in package/__init__.py

from . import logging 
+0

usando su ejemplo parece funcionar. Sin embargo, ahora debo referirme a la clase Logging como logging. Logging. Pruebas adicionales revelan que "desde el registro de importación de registro" no parece funcionar como sugiere PEP 328. Todavía no entiendo por qué "desde el registro de importación de paquetes no funciona". ¿No es una importación absoluta? – kierse

+0

¿Qué versión de python estás usando? Si es una versión anterior (digamos 2.4) las importaciones relativas pueden no funcionar, o al menos, no funcionar como se esperaba. – Soviut

+0

Estoy ejecutando Python 2.6.2 – kierse

9

importaciones relativas y absolutas (PEP 328) no son el problema aquí.

Lo que sucede es que cuando se importa un módulo en un paquete, se agrega implícitamente al espacio de nombres de este paquete. Entonces

from package.logging import Logging 

no solo agrega 'Logging' al paquete. _dict _, pero también agrega 'logging' (el nuevo módulo local de importación) al paquete. _dict _. Entonces primero importa el registro (el módulo de nivel superior) y está disponible como package.logging, y luego sobrescribe esta variable con el módulo local. Esto básicamente significa que no puede tener un paquete.logging para acceder al módulo de nivel superior y a su módulo local, como se esperaba.

En este caso específico, es probable que no desee "exportar" el módulo de registro de nivel superior como un nombre público. En lugar de hacer:

from logging import config as _config 
def main(): 
    _config.fileConfig(...) 
+0

Wow, acabo de enterarme de una nueva versión de Python. Necesitaba probarlo yo mismo y es exactamente lo que dices. Si alguien más quiere verificar esto, simplemente agregue 'print logging' después de' from package.logging import Logging'. –

Cuestiones relacionadas