web-dev-qa-db-fra.com

Importation à partir d’un chemin relatif dans Python

J'ai un dossier pour mon code client, un dossier pour mon code serveur et un dossier pour le code partagé entre eux

Proj/
    Client/
        Client.py
    Server/
        Server.py
    Common/
        __init__.py
        Common.py

Comment importer Common.py depuis Server.py et Client.py?

82
Drew

EDIT Nov 2014 (3 ans plus tard):

Python 2.6 et 3.x prennent en charge les importations relatives appropriées, dans lesquelles vous pouvez éviter de faire quoi que ce soit. Avec cette méthode, vous savez que vous obtenez une importation relative plutôt qu'une importation absolue. Le '..' signifie, allez dans le répertoire au dessus de moi:

from ..Common import Common

À titre de mise en garde, cela ne fonctionnera que si vous exécutez votre python en tant que module, à partir de extérieur du paquet. Par exemple:

python -m Proj

Façon originale de hacky

Cette méthode est encore couramment utilisée dans certaines situations, où vous n’installez jamais votre paquet. Par exemple, il est populaire auprès des utilisateurs Django.

Vous pouvez ajouter Common/à votre sys.path (la liste des chemins python cherche à importer des éléments):

import sys, os
sys.path.append(os.path.join(os.path.dirname(__file__), '..', 'Common'))
import Common

os.path.dirname(__file__) vous donne simplement le répertoire dans lequel se trouve votre fichier python actuel), puis nous allons dans le répertoire "Common /" et importons le module "Common".

121
Dave

Ne faites pas d'importation relative.

De PEP8 :

Les importations relatives pour les importations intra-colis sont fortement découragées.

Mettez tout votre code dans un super package (c'est-à-dire "myapp") et utilisez des sous-packages pour le code client, serveur et commun.

Mise à jour: " Python 2.6 et 3.x prennent en charge les importations relatives appropriées (...)". Voir réponses de Dave pour plus de détails.

12
Michał Šrajer

Assez drôle, un même problème que je viens de rencontrer, et je reçois ce travail de la manière suivante:

en combinant avec la commande linux ln, nous pouvons faire beaucoup plus simple:

1. cd Proj/Client
2. ln -s ../Common ./

3. cd Proj/Server
4. ln -s ../Common ./

Et maintenant, si vous voulez importer some_stuff du fichier: Proj/Common/Common.py dans votre dossier: Proj/Client/Client.py, juste comme ça:

# in Proj/Client/Client.py
from Common.Common import some_stuff

Et la même chose s'applique à Proj/Server, Travaille aussi pour setup.py processus, ne même question discutée ici , espérons que cela aide!

7
jacoolee

Faire une importation relative est absolument OK! Voici ce que mon petit ami fait:

#first change the cwd to the script path
scriptPath = os.path.realpath(os.path.dirname(sys.argv[0]))
os.chdir(scriptPath)

#append the relative location you want to import from
sys.path.append("../common")

#import your module stored in '../common'
import common.py
6
Gary Beardsley

La méthode d'importation par défaut est déjà "relative", à partir de PYTHONPATH. Par défaut, PYTHONPATH se trouve dans certaines bibliothèques système avec le dossier du fichier source d'origine. Si vous exécutez un module avec -m, le répertoire en cours est ajouté à PYTHONPATH. Donc si le point d’entrée de votre programme est à l’intérieur de Proj, alors utilisez import Common.Common devrait fonctionner à la fois dans Server.py et Client.py.

Ne faites pas une importation relative. Cela ne fonctionnera pas comme vous le souhaitez.

4
Jonathan Sternberg