786 votes

L'importation d'un module à partir d'un chemin d'accès relatif

Comment puis-je importer un module python donné son chemin relatif?

Par exemple, si dirFoo contient Foo.py et dirBar, et dirBar contient Bar.py, comment puis-je importer Bar.py en Foo.py?

Voici une représentation visuelle:

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Foo souhaite inclure Bar, mais la restructuration de la hiérarchie de dossiers, n'est pas une option.

348voto

sorin Points 23747

En supposant que les deux répertoires sont de véritables paquets python (ont l' __init__.py le fichier à l'intérieur), voici une solution sûre pour l'inclusion de modules relativement à l'emplacement du script.

Je suppose que vous voulez faire cela, parce que vous avez besoin d'un ensemble de modules avec votre script. - Je l'utiliser dans la production de plusieurs produits, et qui travaille dans de nombreux scénarios spéciaux comme: des scripts appelés à partir d'un autre répertoire ou exécuté avec python exécutée à la place de l'ouverture d'un nouvel interprète.

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if script is called in different ways on Windows
 # __file__ fails if someone does os.chdir() before
 # sys.argv[0] also fails because it doesn't not always contains the path

En bonus, cette approche ne vous permettent de force Python pour utiliser votre module à la place de ceux installés sur le système.

Avertissement! Je ne sais pas vraiment ce qui se passe lorsque les cours du module à l'intérieur d'un egg le fichier. Probablement il échoue également. Ajouter un commentaire si vous avez vraiment besoin d'une meilleure solution, je peut investir quelques heures de plus pour l'améliorer.

331voto

S.Lott Points 207588

Assurez-vous que dirBar a l' __init__.py le fichier -- ce qui fait un répertoire dans un paquet Python.

264voto

Andrew Cox Points 5458

Vous pouvez également ajouter le sous-répertoire de votre python chemin de sorte qu'il importe en caractères normaux.

import sys
sys.path.append( <path to dirFoo> )
import Bar

117voto

lefakir Points 1637

Pourquoi ne pas le faire ?

import os, sys
lib_path = os.path.abspath('../../../lib')
sys.path.append(lib_path)

import mymodule

77voto

bouvard Points 2449

(C'est de mémoire donc si quelqu'un edit si je fais une faute de frappe, s'il vous plaît.)

Si la structure de votre projet, de cette façon:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

Puis, à partir de Foo.py vous devriez être en mesure de le faire:

import dirFoo.Foo

Ou:

from dirFoo.Foo import FooObject

EDIT 1:

Par Tom commentaire, cela impose que l' src le dossier est accessible soit par l'intermédiaire d' site_packages ou dans votre chemin de recherche. Aussi, comme il le mentionne, __init__.py est implicitement importés lors de la première importation d'un module dans ce package/répertoire. Typiquement __init__.py est tout simplement un fichier vide.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X