343 votes

Chemins relatifs en Python

Je construis un simple script d'aide pour le travail qui copiera un couple de fichiers modèles dans notre base de code dans le répertoire actuel. Cependant, je n'ai pas le chemin absolu vers le répertoire où les modèles sont stockés. Je dispose d'un chemin relatif à partir du script mais lorsque j'appelle le script, il traite cela comme un chemin relatif au répertoire de travail actuel. Existe-t-il un moyen de spécifier que cette url relative provient plutôt de l'emplacement du script ?

464voto

Jason Baker Points 56682

Dans le fichier qui contient le script, vous voulez faire quelque chose comme ceci :

import os
dirname = os.path.dirname(__file__)
filename = os.path.join(dirname, 'relative/path/to/file/you/want')

Cela vous donnera le chemin absolu vers le fichier que vous recherchez. Notez que si vous utilisez setuptools, vous devriez probablement utiliser sa commande paquetage des ressources API à la place.

UPDATE : Je réponds à un commentaire ici pour pouvoir coller un échantillon de code :-).

Ai-je raison de penser que __file__ n'est pas toujours disponible (par exemple, lorsque vous exécutez directement le fichier au lieu de l'importer) ?

Je suppose que vous voulez dire le __main__ script lorsque vous mentionnez l'exécution directe du fichier. Si c'est le cas, cela ne semble pas être le cas sur mon système (python 2.5.1 sur OS X 10.5.7) :

#foo.py
import os
print os.getcwd()
print __file__

#in the interactive interpreter
>>> import foo
/Users/jason
foo.py

#and finally, at the shell:
~ % python foo.py
/Users/jason
foo.py

Cependant, je sais qu'il y a quelques bizarreries avec __file__ sur les extensions C. Par exemple, je peux faire ceci sur mon Mac :

>>> import collections #note that collections is a C extension in Python 2.5
>>> collections.__file__
'/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/lib-
dynload/collections.so'

Cependant, cela soulève une exception sur ma machine Windows.

1 votes

Ai-je raison de penser que fichier n'est pas toujours disponible (par exemple, lorsque vous exécutez directement le fichier au lieu de l'importer) ?

0 votes

@Stephen Edmonds J'utilise un fichier que j'exécute, plutôt que d'importer, et cela fonctionne très bien.

25 votes

Notez que vous devriez utiliser os.path.join partout pour des raisons de portabilité : filename = os.path.join(dir, 'relative', 'path', 'to', 'file', 'you' , 'want')

75voto

user989762 Points 367

Vous avez besoin os.path.realpath (l'exemple ci-dessous ajoute le répertoire parent à votre chemin)

import sys,os
sys.path.append(os.path.realpath('..'))

2 votes

os.path.dirname(__file__) m'a donné une chaîne vide. Cela a parfaitement fonctionné.

5 votes

Cela semble donner le parent du répertoire à partir duquel le script est exécuté, et non de l'emplacement du script.

21 votes

os.path.realpath('..') vous donne le répertoire parent du répertoire de travail actuel . C'est généralement pas ce que vous voulez.

12voto

Tom Leys Points 10453

Voir sys.path Comme initialisé au démarrage du programme, le premier élément de cette liste, path[0], est le répertoire contenant le script qui a été utilisé pour invoquer l'interpréteur Python.

Utilisez ce chemin comme le dossier racine à partir duquel vous appliquer votre chemin relatif

>>> import sys
>>> import os.path
>>> sys.path[0]
'C:\\Python25\\Lib\\idlelib'
>>> os.path.relpath(sys.path[0], "path_to_libs") # if you have python 2.6
>>> os.path.join(sys.path[0], "path_to_libs")
'C:\\Python25\\Lib\\idlelib\\path_to_libs'

3 votes

Ce n'est pas forcément vrai. Habituellement, sys.path[0] est une chaîne vide ou un point, qui est un chemin relatif au répertoire actuel. Si vous voulez le répertoire courant, utilisez os.getcwd.

0 votes

L'expéditeur initial a fait remarquer que le répertoire de travail actuel n'est pas le bon endroit pour baser le chemin relatif. Vous avez raison de dire que sys.path[0] n'est pas toujours valide.

0 votes

Non, sys.path[0] n'est pas toujours défini comme le répertoire parent. Le code Python peut être invoqué avec -c ou -m ou par l'intermédiaire d'un interprète intégré, auquel point sys.path[0] est réglé sur quelque chose de tout à fait différent.

4voto

user3076704 Points 1

Bonjour, tout d'abord, vous devez comprendre les fonctions os.path.abspath(path) et os.path.relpath(path)

En bref os.path.abspath(path) fait un chemin relatif à chemin absolu . Et si le chemin fourni est lui-même un chemin absolu, la fonction renvoie le même chemin.

de même os.path.relpath(path) fait un chemin absolu à chemin relatif . Et si le chemin fourni est lui-même un chemin relatif, la fonction renvoie le même chemin.

L'exemple ci-dessous vous permettra de bien comprendre le concept ci-dessus. :

Supposons que j'ai un fichier liste_de_fichiers_d'entrée.txt qui contient la liste des fichiers d'entrée à traiter par mon script python.

D:\conc\input1.dic

D:\conc\input2.dic

D:\Copyioconc\input_file_list.txt

Si vous voyez la structure du dossier ci-dessus, liste_de_fichiers_d'entrée.txt est présent dans Copie de l'accord et les fichiers à traiter par le script python sont présents dans le dossier conc dossier

Mais le contenu du fichier liste_de_fichiers_d'entrée.txt est comme indiqué ci-dessous :

.. \conc\input1.dic

.. \conc\input2.dic

Et mon python script est présent dans D : conduire.

Et le chemin relatif fourni dans le liste_de_fichiers_d'entrée.txt sont relatifs au chemin du fichier liste_de_fichiers_d'entrée.txt fichier.

Ainsi, lorsque python script sera exécuté le répertoire de travail courant (utiliser os.getcwd() pour obtenir le chemin)

Comme mon chemin relatif est relatif à liste_de_fichiers_d'entrée.txt c'est-à-dire " D:\Copyofconc " je dois changer le répertoire de travail actuel en " D:\Copyofconc " .

Je dois donc utiliser os.chdir(' D:\Copyofconc ') Le répertoire de travail actuel sera donc " D:\Copyofconc " .

Maintenant, pour obtenir les fichiers input1.dic et input2.dic je vais lire les lignes \conc\input1.dic ", il faut alors utiliser la commande

input1_path= os.path.abspath(' \conc\input1.dic ') (pour changer le chemin relatif en chemin absolu. Ici, le répertoire de travail actuel est " D:\Copyofconc ", le fichier " . \conc\input1.dic " est accessible par rapport à " D:\Copyofconc ")

donc chemin d'entrée 1 est " D:\conc\input1.dic "

-2voto

Samy Bencherif Points 116

Je ne sais pas si cela s'applique à certaines des anciennes versions, mais je crois que Python 3.3 prend en charge les chemins relatifs en natif.

Par exemple, le code suivant devrait créer un fichier texte dans le même dossier que le script python script :

open("text_file_name.txt", "w+t")

(notez qu'il ne devrait pas y avoir de forward ou de backslash au début si c'est un chemin relatif)

0 votes

Exact, donc cela fonctionnera à partir du CWD, ce qui n'est pas ce que le PO demande. Ils veulent travailler à partir de l'emplacement des scripts.

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