Importer des fichiers à partir d'un autre dossier

j'ai la structure de dossier suivante.

application/app/folder/file.py

et je veux importer quelques fonctions de file.py dans un autre fichier Python qui réside dans

application/app2/some_folder/some_file.py

j'ai essayé

from application.app.folder.file import func_name

et quelques autres tentatives diverses, mais jusqu'à présent, je ne parvenais pas à importer correctement. Comment puis-je faire cela?

752
demandé sur Billal Begueradj 2010-12-08 05:07:15

21 réponses

par défaut, vous ne pouvez pas. Lors de l'importation d'un fichier, Python ne recherche que le répertoire courant, le répertoire d'où le script d'entrée s'exécute, et sys.path qui inclut des localisations telles que le répertoire d'installation du paquet (c'est en fait un peu plus complexe que cela, mais cela couvre la plupart des cas).

cependant, vous pouvez ajouter au chemin Python à l'exécution:

# some_file.py
import sys
sys.path.insert(0, '/path/to/application/app/folder')

import file
862
répondu Cameron 2010-12-08 02:32:12

Rien de mal avec:

from application.app.folder.file import func_name

assurez-vous que dossier contient aussi un __init__.py , ce qui permet de l'inclure dans un paquet. Je ne sais pas pourquoi les autres réponses parlent de PYTHONPATH.

429
répondu joey 2014-02-24 18:27:45

quand les modules sont dans des emplacements parallèles, comme dans la question:

application/app2/some_folder/some_file.py
application/app2/another_folder/another_file.py

cette abréviation rend un module visible à l'autre:

import sys
sys.path.append('../')
48
répondu slizb 2016-12-11 01:56:10

je pense qu'une façon ad hoc serait d'utiliser la variable d'environnement PYTHONPATH comme décrit dans la documentation: Python2 , Python3

# Linux & OSX
export PYTHONPATH=$HOME/dirWithScripts/:$PYTHONPATH

# Windows
set PYTHONPATH=C:\path\to\dirWithScripts\;%PYTHONPATH%
33
répondu Ax3l 2018-09-24 23:04:05

De ce que je sais, ajouter un __init__.py fichier directement dans le dossier des fonctions que vous souhaitez importer fera le travail.

22
répondu Vaibhav Singh 2015-10-14 11:48:02

les réponses ici manquent de clarté, ceci est testé sur Python 3.6

avec cette structure de chemise:

main.py
|
---- myfolder/myfile.py

myfile.py a le contenu:

def myfunc():
    print('hello')

la déclaration d'importation dans main.py est:

from myfolder.myfile import myfunc
myfunc()

et ceci imprimera hello .

17
répondu danday74 2018-03-26 12:51:33

considérant application comme le répertoire racine de votre projet python, créez un fichier __init__.py vide dans les répertoires application , app et folder . Puis dans votre some_file.py faites les changements suivants pour obtenir la définition de func_name:

import sys
sys.path.insert(0, r'/from/root/directory/application')

from application.app.folder.file import func_name ## You can also use '*' wildcard to import all the functions in file.py file.
func_name()
16
répondu ChandanK 2017-11-06 16:32:59

a travaillé pour moi en python3 sur linux

import sys  
sys.path.append(pathToFolderContainingScripts)  
from scriptName import functionName #scriptName without .py extension  
14
répondu dsg38 2016-08-16 15:24:27

votre problème est que Python cherche dans le répertoire Python ce fichier et ne le trouve pas. Vous devez spécifier que vous parlez du répertoire dans lequel vous êtes et non de celui de Python.

pour faire ceci vous changez ceci:

from application.app.folder.file import func_name

à ceci:

from .application.app.folder.file import func_name

en ajoutant le point vous dites regarder dans ce dossier pour le dossier d'application au lieu de regarder dans le Python répertoire.

12
répondu CianB 2018-03-26 12:54:15

Première import sys

 import sys

Deuxième ajouter le chemin du dossier

sys.path.insert(0, '/the/folder/path/name-folder/')

Third faire un fichier blanc appelé __ init __.py dans votre sous-répertoire (cela indique à Python que c'est un module)

  • name-file.py
    • nom-dossier
      • _ _ init __.1519210920"
      • name-module.py

Quatrième importer le module à l'intérieur du dossier

from name-folder import name-module
12
répondu Alex Montoya 2018-05-22 18:54:01

cela fonctionne pour moi sur windows

# some_file.py on mainApp/app2 
import sys
sys.path.insert(0, sys.path[0]+'\app2')

import some_file
11
répondu Emeeus 2016-10-29 13:19:16

Essayer Python relative des importations:

from ...app.folder.file import func_name

chaque point dirigeant est un autre niveau supérieur dans la hiérarchie commençant par le répertoire courant.


problèmes? Si cela ne fonctionne pas pour vous, alors vous êtes probablement mordu par les nombreuses importations relatives de gotcha A. Lire les réponses et les commentaires pour plus de détails: Comment réparer "Tentée par rapport à l'importation de non-package" même avec __init__.py

indice: avoir __init__.py à chaque niveau de répertoire. Vous pourriez avoir besoin de python -m application.app2.some_folder.some_file (départ .py) que vous exécutez à partir du répertoire de haut niveau ou que vous avez ce répertoire de haut niveau dans votre PYTHONPATH. Phew!

8
répondu Zectbumo 2017-12-17 08:43:45

utilisant sys.chemin.ajouter avec un chemin absolu n'est pas idéal pour déplacer l'application vers d'autres environnements. Utiliser un chemin relatif ne fonctionnera pas toujours car le répertoire de travail actuel dépend de la façon dont le script a été invoqué.

puisque la structure du dossier d'application est fixe, nous pouvons utiliser os.chemin d'accès pour obtenir le chemin complet du module, on souhaite importer. Par exemple, si c'est la structure:

/home/me/application/app2/some_folder/vanilla.py
/home/me/application/app2/another_folder/mango.py

Et disons que vous voulez pour importer le module" mango". Vous pouvez faire ce qui suit en vanilla.py:

import sys, os.path
mango_dir = (os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
+ '/another_folder/')
sys.path.append(mango_dir)
import mango

bien sûr, vous n'avez pas besoin de la variable mango_dir.

pour comprendre comment cela fonctionne, regardez cet exemple de session interactive:

>>> import os
>>> mydir = '/home/me/application/app2/some_folder'
>>> newdir = os.path.abspath(os.path.join(mydir, '..'))
>>> newdir
    '/home/me/application/app2'
>>> newdir = os.path.abspath(os.path.join(mydir, '..')) + '/another_folder'
>>> 
>>> newdir
'/home/me/application/app2/another_folder'
>>> 

et vérifiez le os.chemin de la documentation.

6
répondu Nagev 2018-05-11 16:18:49

si le but de charger un module à partir d'un chemin spécifique est de vous aider lors du développement d'un module personnalisé, vous pouvez créer un lien symbolique dans le même dossier du script de test qui pointe vers la racine du module personnalisé. Cette référence de module aura la priorité sur tous les autres modules installés du même nom pour tout script exécuté dans ce dossier.

j'ai testé cela sur Linux mais cela devrait fonctionner dans n'importe quel OS moderne qui supporte des liens symboliques.

L'un des avantages de cette approche est que vous pouvez pointer vers un module qui se trouve dans votre copie de travail locale SVC branch, ce qui peut grandement simplifier le cycle de développement et réduire les modes de défaillance de la gestion des différentes versions du module.

5
répondu Timothy C. Quinn 2015-12-23 15:42:47

je suis assez spécial : J'utilise Python avec Windows !

Je ne fais que compléter l'information : Pour Windows et Linux, les chemins relatifs et absolus fonctionnent en sys.path (j'ai besoin de chemins relatifs parce que j'utilise mes scripts sur plusieurs PC et sous différents répertoires principaux).

et lorsque vous utilisez Windows \ et / peuvent être utilisés comme séparateur pour les noms de fichiers et, bien sûr, vous devez doubler \ en Python cordes,

quelques exemples valables:

sys.path.append('c:\tools\mydir')
sys.path.append('..\mytools')
sys.path.append('c:/tools/mydir')
sys.path.append('../mytools')

(note : je pense que / est plus pratique que de \ , même si c'est moins "Windows natif" parce que c'est Linux-compatible et plus simple à écrire et copie de l'explorateur Windows)

5
répondu geekobi 2017-03-18 12:36:16

alors j'ai cliqué à droite sur mon IDE, et j'ai ajouté un nouveau folder et je me demandais pourquoi je n'étais pas en mesure d'importer de celui-ci. Plus tard, j'ai réalisé que je devais faire un clic droit et créer un paquet Python, et non un dossier classic du système de fichiers. Ou une méthode post-mortem en ajoutant un __init__.py (qui fait que python traite le dossier du système de fichiers comme un paquet) comme mentionné dans d'autres réponses. Ajouter cette réponse ici juste au cas où quelqu'un aurait pris cette route.

1
répondu mithunpaul 2018-07-27 01:27:08

vous pouvez rafraîchir le shell Python en appuyant sur f5, ou aller à Run-> Run Module. De cette façon, vous n'avez pas à changer le répertoire pour lire quelque chose du fichier. Python changera automatiquement le répertoire. Mais si vous voulez travailler avec différents fichiers de différents répertoires dans L'interpréteur de commandes de Python, alors vous pouvez changer le répertoire dans sys, comme Cameron l'a dit plus tôt .

0
répondu IOstream 2017-07-12 22:54:15

dans mon cas, j'avais une classe à importer. Mon dossier ressemblait à ceci:

# /opt/path/to/code/log_helper.py
class LogHelper:
    # stuff here

Dans mon fichier principal, j'ai inclus le code par:

path.append("/opt/path/to/code/")
from log_helper import LogHelper
0
répondu schmudu 2017-11-30 00:15:10

en Python 3.4 et plus tard, vous pouvez importer à partir d'un fichier source directement (lien vers la documentation) .

voici un exemple. Premièrement, le fichier à importer, appelé foo.py :

def announce():
    print("Imported!")

Le code qui importe le fichier ci-dessus, fortement inspiré par l'exemple dans la documentation:

import importlib, importlib.util, os.path

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

foo = module_from_file("foo", "/path/to/foo.py")

if __name__ == "__main__":
    print(foo)
    print(dir(foo))
    foo.announce()

La sortie:

<module 'foo' from '/path/to/foo.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!

notez que le nom de la variable, le le nom du module et le nom du fichier ne doivent pas nécessairement correspondre. Ce code fonctionne toujours:

import importlib, importlib.util, os.path

def module_from_file(module_name, file_path):
    spec = importlib.util.spec_from_file_location(module_name, file_path)
    module = importlib.util.module_from_spec(spec)
    spec.loader.exec_module(module)
    return module

baz = module_from_file("bar", "/path/to/foo.py")

if __name__ == "__main__":
    print(baz)
    print(dir(baz))
    baz.announce()

La sortie:

<module 'bar' from '/path/to/foo.py'>
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'announce']
Imported!

modules d'importation programmatique a été introduit en python 3.1 et vous donne plus de contrôle sur la façon dont les modules sont importés. Reportez-vous à la documentation pour plus d'informations.

0
répondu wecsam 2018-07-30 01:12:08

j'ai été confronté au même défi, en particulier lors de l'importation de plusieurs fichiers, c'est comment j'ai réussi à le surmonter.

import os, sys

from os.path import dirname, join, abspath
sys.path.insert(0, abspath(join(dirname(__file__), '..')))

from root_folder import file_name
0
répondu Erick Mwazonga 2018-10-01 07:07:37
sys.path.insert(0, '/path/to/application/app/folder')
-2
répondu Mickey Yang 2017-03-18 09:00:33