2009-10-17 7 views
2

J'ai une structure de répertoire qui ressemble à ceci:Comment faire pour que ces importations relatives fonctionnent dans Python 3?

project/ 
     __init__.py 
     foo/ 
      __init.py__ 
      first.py 
      second.py 
      third.py 
     plum.py 

Dans project/foo/__init__.py j'importer des classes de first.py, second.py et third.py et les mettre en __all__.

Il y a une classe nommée first.pyWonderfulThing que je voudrais utiliser dans second.py, et que vous voulez importer par l'importation * de foo. (Il est hors de la portée de cette question pourquoi je voudrais le faire, supposons que j'ai une bonne raison.)

En second.py J'ai essayé from .foo import *, from foo import * et from . import * et dans aucun de ces cas est WonderfulThing importé . J'ai également essayé from ..foo import *, ce qui soulève une erreur "Tentative d'importation relative au-delà du paquet toplevel". J'ai lu les documents et le PEP, et je n'arrive pas à comprendre comment faire fonctionner ce document. Toute aide serait appréciée.

Clarification/Edit: Il semble que je puisse avoir mal compris la façon dont fonctionne __all__ dans les paquets. Je l'ai utilisé les mêmes que dans les modules,

from .first import WonderfulThing 
__all__ = [ "WonderfulThing" ] 

mais en regardant les documents encore, il semble suggérer que __all__ ne peuvent être utilisés dans des emballages pour spécifier les noms des modules à importer par défaut; il ne semble pas y avoir moyen d'inclure quelque chose qui ne soit pas un module.

Est-ce correct?

Modifier: Une importation non générique a échoué (cannot import name WonderfulThing). Essayer from . import foo a échoué, mais import foo fonctionne. Malheureusement, dir(foo) ne montre rien.

+0

fonctionne-t-il sans l'importation générique? (C'est-à-dire, pouvez-vous importer WonderfulThing de manière explicite?) Les importations relatives peuvent être délicates par elles-mêmes.Je suggère que vous vous assuriez que cela fonctionne avant de passer à __all__. –

+2

'__all__' peut contenir les noms de tous les objets. Ils ne doivent pas être (et ne sont généralement pas) seulement des modules. –

+0

"Malheureusement, dir (foo) ne montre rien." Rien!? Pour moi il montre '['WonderfulThing', '__all__', '__builtins__', '__doc__', '__file__', '__name__', '__package__', '__path__', 'first']' Vous devez faire quelque chose fondamentalement faux, ou vous ne nous montrez pas le code réel, parce que ce que vous décrivez fonctionne bien. –

Répondre

3

Editer: J'ai mal compris la question: Non __all__ n'est pas limité aux seuls modules.

Une question est pourquoi vous voulez faire une importation relative. Il n'y a rien de mal à faire from project.foo import *, ici. Deuxièmement, la restriction __all__ sur foo ne vous empêchera pas de faire from project.foo.first import WonderfulThing, ou juste from .first import WonderfulThing, ce qui sera toujours le meilleur moyen.

Et si vous voulez vraiment importer beaucoup de choses, il est probablement préférable de faire from project import foo, puis utilisez les choses avec foo.WonderfulThing au lieu de faire un import * puis en utilisant WonderfulThing directement.

Cependant, pour répondre à votre question directe, d'importer à partir du fichier __init__ dans second.py vous faites ceci:

from . import WonderfulThing 

ou

from . import * 
Questions connexes