2009-08-11 8 views
5

Je rencontre des problèmes avec mes propres modules remplaçant ceux construits en Python (en particulier le module de journalisation). Voici ma mise en page du projet:Un autre problème d'importation absolue

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

run.py

from package import main 

main() 
package

/__ init__.py

from __future__ import absolute_import 
import logging 
import logging.config 

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

/enregistrement/__ init__.py

class Logging(object): 
    pass 

Comme se trouve maintenant, le code ci-dessus fonctionne. Dès que je tente d'importer la classe d'enregistrement de package.logging comme ceci:

from __future__ import absolute_import 

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

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

Je reçois une erreur:

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

J'ai lu les notes de version PEP 328 et constaté que les importations absolues être plutôt simple. Malheureusement, je n'ai pas été en mesure de comprendre celui-ci.

Qu'est-ce qui me manque ici?

Répondre

1

Vous pouvez utiliser relative imports pour forcer où python recherche les premiers modules:

in package/__init__.py

from . import logging 
+0

en utilisant votre exemple semble fonctionner. Cependant, je dois maintenant me référer à la classe Logging en tant que logging.Logging. D'autres tests révèlent que "from .logging import Logging" ne semble pas fonctionner comme le suggère le PEP 328. Je ne comprends toujours pas pourquoi "from package.logging import Logging" ne fonctionne pas. N'est-ce pas une importation absolue? – kierse

+0

quelle version de python utilisez-vous? Si c'est une version plus ancienne (disons 2.4), les importations relatives peuvent ne pas fonctionner, ou du moins, ne pas fonctionner comme prévu. – Soviut

+0

Je cours Python 2.6.2 – kierse

9

importations relatives et absolues (PEP 328) ne sont pas le problème ici.

Ce qui se passe est que lorsqu'un module d'un package est importé, il est implicitement ajouté à l'espace de noms de ce package. Donc

from package.logging import Logging 

ajoute non seulement 'Logging' au package. _dict _, mais ajoute également 'logging' (le module local nouvellement importé) au package. _dict _. Vous devez d'abord importer la consignation (le module de niveau supérieur) et il est disponible en tant que package.logging, puis vous remplacez cette variable par le module local. Cela signifie essentiellement que vous ne pouvez pas avoir de package.logging pour accéder au module de niveau supérieur et à votre module local, comme prévu.

Dans ce cas précis, vous ne souhaitez probablement pas "exporter" le module de journalisation de niveau supérieur en tant que nom public. Au lieu de faire:

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

Wow, viens d'apprendre un nouveau Gotcha Python. J'avais besoin de tester cela moi-même et c'est exactement comme tu dis. Si quelqu'un d'autre veut le vérifier, il suffit d'ajouter 'print logging' après' 'from \ package.logging import Logging'. –

Questions connexes