2010-11-14 30 views
27

Salut à tous - Je tire mes cheveux avec des importations relatives en Python. J'ai lu la documentation 30 fois et de nombreux messages ici sur SO et d'autres forums - ne semble toujours pas fonctionner.Importations relatives en Python

Ma structure de répertoire ressemble actuellement à ce

src/ 
    __init__.py 
    main.py 
    components/ 
     __init__.py 
     expander.py 
     language_id.py 
    utilities/ 
     __init__.py 
     functions.py 

Je veux expander.py et language_id.py d'avoir accès au module de fonctions. Je lance python main.py qui accède très bien aux modules depuis components.expander import * et components.language_id import *.

Cependant, le code à l'intérieur d'extension et language_id pour accéder au module Fonctions:

from ..utilities.functions import * 

Je reçois cette erreur:

ValueError: Attempted relative import beyond toplevel package 

Je suis allé sur un certain nombre de fois et il semble suivez la documentation. Quelqu'un a des idées de ce qui ne va pas ici?

+8

Vous avez déjà trouvé la solution, mais pour expliquer pourquoi c'est nécessaire: le paquet devrait être entièrement autonome. Il ne traitera pas src/comme un paquet lorsque vous exécutez main.py à l'intérieur. –

Répondre

21

Nevermind je l'ai résolu:

src/ 
    main.py 
    mod/ 
     __init__.py 
     components/ 
      __init__.py 
      expander.py 
      language_id.py 
     utilities/ 
      __init__.py 
      functions.py 

main.py se réfère alors aux sous-paquets comme:

from mod.components.expander import * 
from mod.utilities.functions import * 

expander.py et language_id.py avoir accès à functions.py avec:

from ..utilities.functions import * 

Mais la chose intéressante est que j'avais un fichier texte dans le répertoire des composants qui expander.py nous es. Cependant, lors de l'exécution, il n'a pas pu localiser le fichier même s'il se trouvait dans le même répertoire. J'ai déplacé le fichier texte dans le même répertoire que main.py et cela a fonctionné. Cela semble contre-intuitif.

+13

Tout le nouveau module d'importation est cassé et non intuitif. –

+3

L'ouverture de fichiers texte s'effectue à partir du répertoire de travail dans lequel vous avez démarré le programme, tandis que l'importation est relative à l'emplacement du script. Vous pouvez utiliser \ _ \ _ fichier \ _ \ _ dans un module pour trouver son chemin, et donc faire référence à des choses dans le même répertoire, même si ce n'est pas très élégant. Si le fichier texte est des données statiques pour le programme, il peut être plus facile de le transformer en un module Python et de l'importer. –

+1

Vous pouvez utiliser 'pkgutil.get_data()' (http://docs.python.org/library/pkgutil#pkgutil.get_data) pour récupérer des fichiers en utilisant l'espace de nom du module pour les localiser. Par exemple, 'raw_data = pkgutil.get_data ('mod.components', 'data.txt')' récupèrera les données binaires brutes du fichier. – ncoghlan