2009-08-11 11 views
5

Ho problemi con i miei moduli che sovrascrivono quelli in Python (in particolare il modulo di registrazione). Ecco il mio layout del progetto:Un altro problema di importazione assoluta

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

run.py

from package import main 

main() 

pacchetto/__ init__.py

from __future__ import absolute_import 
import logging 
import logging.config 

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

pacchetto/logging/__ init__.py

class Logging(object): 
    pass 

Come sta ora, il codice sopra funziona. Non appena si tenta di importare la classe di registrazione da package.logging in questo modo:

from __future__ import absolute_import 

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

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

ottengo un errore:

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

Ho letto le note di rilascio PEP 328 e ho trovato le importazioni assoluti di essere piuttosto semplice. Sfortunatamente non sono stato in grado di capirlo.

Cosa mi manca qui?

risposta

1

È possibile utilizzare relative imports per forzare dove pitone cerca i moduli prima:

in package/__init__.py

from . import logging 
+0

utilizzare l'esempio sembra funzionare. Tuttavia, ora devo fare riferimento alla classe Logging come logging.Logging. Ulteriori test rivelano che "da .logging import Logging" non sembra funzionare come suggerisce PEP 328. Ancora non capisco perché "da package.logging import Logging" non funzioni. Non è un'importazione assoluta? – kierse

+0

quale versione di python stai usando? Se è una versione precedente (diciamo 2.4) le importazioni relative potrebbero non funzionare o, almeno, non funzionare come previsto. – Soviut

+0

Sto eseguendo Python 2.6.2 – kierse

9

importazioni relativi e assoluti (PEP 328) non sono il problema qui.

Quello che succede è che quando un modulo in un pacchetto viene importato, viene implicitamente aggiunto allo spazio dei nomi di questo pacchetto. Quindi

from package.logging import Logging 

non solo aggiunge "Registrazione" al pacchetto. _dict _, ma aggiunge anche 'logging' (il modulo locale di importazione recente) al pacchetto. _dict _. Quindi si importa prima la registrazione (il modulo di livello superiore) ed è disponibile come package.logging, quindi si sovrascrive questa variabile con il modulo locale. Ciò significa fondamentalmente che non è possibile avere un pacchetto. Log per accedere al modulo di livello superiore e al modulo locale, come previsto.

In questo caso specifico, probabilmente non si desidera "esportare" il modulo di registrazione di livello superiore come nome pubblico. Invece:

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

Wow, ho appena imparato un nuovo trucco di Python. Avevo bisogno di testarlo da solo ed è esattamente come dici tu. Se qualcun altro vuole verificarlo, basta aggiungere 'print logging' dopo' da package.logging import Logging'. –

Problemi correlati