Comment ajouter un module Python à syspath?

69

J'ai une structure de fichier comme celle-ci:

Folder
   Common
      foo1.py
   TestFolder
      foo2.py

Je veux importer dans foo2.py et foo1.py. J'ai essayé mais cela ne fonctionne pas sur Ubuntu:

sys.path.append(os.path.abspath('../../'))
from Common import foo1.py
utilisateur284474
la source
Avez-vous un __init__.pyfichier dans votre dossier? C'est ainsi que python crée des packages et vous permet d'importer des modules à partir de ce package. guide.python-distribute.org/creation.html
Bryan
J'ai le fichier init.py dans Common et dans TestFolder
user284474
vous en avez besoin dans le répertoire des dossiers ainsi que dans les sous-dossiers si vous souhaitez importer
Bryan
Cette init .py est vide?
user284474
1
oui, il peut être vide. À moins que vous n'ayez besoin d'une certaine configuration pour votre paquet mais que cela ne vous dérange pas d'être vide
Bryan

Réponses:

115

Comment python trouve ses modules

Strictement pris, un module est un fichier python unique, alors qu'un paquet est un dossier contenant des fichiers python, accompagné d'un fichier (pouvant être vide) nommé __init__.py, pour indiquer à python qu'il s'agit d'un paquet pour importer des modules. Dans les deux cas, les modules ont besoin de leur .pyextension, mais leur importation se fait sans (voir plus bas).

Par défaut, Python recherche ses modules et packages dans $PYTHONPATH.

Pour savoir ce qui est inclus dans $ PYTHONPATH, exécutez le code suivant dans python (3):

import sys
print(sys.path)

Comment ajouter un répertoire

Parfois

À partir d'un fichier python, vous pouvez ajouter occasionnellement des chemins d'accès au chemin par défaut en ajoutant les lignes suivantes dans la section d'en-tête de votre application ou script python:

import sys
sys.path.insert(0, "/path/to/your/package_or_module")

Par exemple:

si j'ai un dossier:, /home/myname/pythonfileset que je veux importer le fichier module_1.pysitué dans ce répertoire, j'ajoute ceci à la section head de mon code:

import sys
sys.path.insert(0, "/home/myname/pythonfiles")

Et je peux simplement importer le fichier module_1.pyen:

import module_1

Lorsque je crée un package et que je veux importer un ou plusieurs modules à partir du package, je dois créer un dossier $PYTHONPATHcontenant les modules, accompagné d'un fichier (pouvant être vide) appelé__init__.py

Par exemple:

Pour importer à partir d' un package (dossier) appelé my_packagedans /home/myname/pythonfiles, ajoutez le /home/myname/pythonfileschemin de votre $PYTHONPATH, comme dans l' exemple 1, et importer le module appelé module_2.py(dans le dossier du package) simplement avec: `

from <packagename> import module_2

Ajouter des répertoires à de $PYTHONPATHfaçon permanente:

Ajoutez la ligne suivante à votre ~/.profilefichier.

export PYTHONPATH=$PYTHONPATH:/path/you/want/to/add

Sous-répertoires

Dans un paquet, les sous-répertoires ne sont pas inclus simplement comme ça; vous devez "chaîner" les répertoires. Pour importer un module module_3.py, dans le dossier du subfolderdossier packagename:

import packagename.subfolder.module_3

Étant donné que tous les sous-dossiers du paquet incluent leur propre __init__.pyfichier.

Lorsqu'un module est dans le même répertoire que le script ou l'application

Il n'est pas nécessaire d'insérer le chemin d'accès à un module lorsqu'il se trouve dans le même répertoire que le script ou l'application, il est automatiquement ajouté.

Exemple:

Si j'ai un dossier contenant script.pyet module.py, je peux simplement importer le module en:

import module
Jacob Vlijm
la source
Je voudrais également suggérer de lire python.org/dev/peps/pep-0328 , en particulier si vous ciblez Python 3 (ou prévoyez de cibler à l’avenir)
zaadeh
Pourquoi est printenv PYTHONPATHrien?
Stevie G
1
sys.path.append("/path/to/your/package_or_module")ajoute également un chemin à la valeur par défaut, ce qui crée moins de confusion. Par rapport à sys.path.insert(0,...)qui a 0comme premier argument.
Paul Rougieux
1
@PaulRougieux: Le problème avec l'ajout au chemin est que votre module peut déjà exister ailleurs dans le chemin (dans un fichier .egg par exemple) et vous allez choisir cette version de votre module au lieu de celle de votre fichier.
Snark
6

La manière correcte d'utiliser l'importation relative est la suivante:

from ..Common import foo1

Et vous avez également besoin d'un __init__.pydans tous vos dossiers.

Sylvain Pineau
la source
1
Merci. Mais si j'ai un module qui est deux dossiers Up comment puis-je importer cela? à partir de .... Le dossier ne fonctionne pas
user284474
Cela fonctionne-t-il avec un seul niveau?
Sylvain Pineau
Avec un seul niveau cela fonctionne.
user284474
ok, pourriez-vous s'il vous plaît accepter cette réponse? pour plusieurs niveaux si vous pouvez poser une autre question , mais d' abord jeter un oeil à cette question et cette réponse la meilleure façon d'appeler vos modules dans un paquet
Sylvain Pineau
Est-ce vrai pour Python 2 ou Python 3? Ou les deux?
alex
2

NB: Cette réponse est obsolète pour la dernière version de Python 3, mais est ici pour la version précédente. Pour plus d'informations, lisez les commentaires et https://www.python.org/dev/peps/pep-0420/


Essentiellement, chaque dossier contenant du code python que vous souhaitez ajouter à syspath nécessite un fichier __init__.py. Ces fichiers __init__.py peuvent être vides.

don.joey
la source
Si je comprends bien, ce n'est plus le cas, le répertoire devient maintenant un "espace de noms".
Aaron Hall
@ AaronHall intéressant, source?
don.joey
1
Essayez ceci comme preuve: python -c "from pathlib import Path; Path('ns').mkdir(); Path('ns/mod.py').write_text('''print('mod.py')'''); import ns.mod; from shutil import rmtree; rmtree('ns')"voici également une documentation pertinente, PEP 420, qui décrit l’ajout de la sémantique du paquet d’espace de nommage
Aaron Hall