190 votes

Ouvrir un fichier dans un emplacement relatif en Python

Suppose my python code is executed a directory called principal and the application needs to access principal/2091/data.txt.

how should I use open(location)? what should the parameter location be?

I found that below simple code will work.. does it have any disadvantages?

fichier = "\2091\sample.txt"
chemin = os.getcwd()+fichier
fp = open(chemin, 'r+');

3 votes

Vous utilisez des barres obliques non échappées. C'est un désavantage.

8 votes

Plusieurs inconvénients. 1) Comme le mentionne @orip, utilisez des barres obliques pour les chemins, même sous windows. Votre chaîne ne fonctionnera pas. Ou utilisez des chaînes brutes comme r"\2091\sample.txt". Ou échappez-les comme "\\2091\\sample.txt" (mais c'est ennuyeux). Aussi, 2) vous utilisez getcwd() qui est le chemin dans lequel vous étiez lorsque vous avez exécuté le script. Je pensais que vous vouliez relatif à l'emplacement du script (mais maintenant je me demande). Et 3), utilisez toujours les fonctions os.path pour manipuler les chemins. Votre ligne de jointure de chemin devrait être os.path.join(os.getcwd(), fichier) 4) le ; est inutile

4 votes

Et pour bien faire... 5) utilisez des context guards pour garder votre code propre et éviter d'oublier de fermer votre fichier: with open(path, 'r+') as fp:. Voir ici pour la meilleure explication des instructions with que j'ai pu trouver.

257voto

Russ Points 2357

Avec ce type de chose, vous devez faire attention à quel est votre répertoire de travail réel. Par exemple, vous ne pouvez pas exécuter le script à partir du répertoire où se trouve le fichier. Dans ce cas, vous ne pouvez pas simplement utiliser un chemin relatif seul.

Si vous êtes sûr que le fichier que vous voulez est dans un sous-répertoire en dessous de l'emplacement réel du script, vous pouvez utiliser __file__ pour vous aider ici. __file__ est le chemin complet de l'emplacement où se trouve le script que vous exécutez.

Vous pouvez donc bidouiller quelque chose comme ceci:

import os
script_dir = os.path.dirname(__file__) #<-- répertoire absolu où se trouve le script
chemin_rel = "2091/data.txt"
chemin_absolu_fichier = os.path.join(script_dir, chemin_rel)

0 votes

J'ai trouvé que le code simple ci-dessous fonctionnera.. a-t-il des inconvénients ? fichier="\sample.txt" chemin=os.getcwd()+str(loc)+fichier fp=open(chemin,'r+');

0 votes

@Arash L'inconvénient est que le cwd (répertoire de travail actuel) peut être n'importe où, et ne sera pas nécessairement l'endroit où se trouve votre script.

5 votes

__file__ est un chemin relatif (du moins sur ma configuration, pour une raison inconnue), et vous devez appeler os.path.abspath(__file__) d'abord. osx/homebrew 2.7

49voto

Fahad Haleem Points 591

Ce code fonctionne bien :

import os

def read_file(file_name):
    file_handle = open(file_name)
    print file_handle.read()
    file_handle.close()

file_dir = os.path.dirname(os.path.realpath('__file__'))
print file_dir

# Pour accéder au fichier dans le même dossier
file_name = "same.txt"
read_file(file_name)

# Pour accéder au fichier dans un dossier contenu dans le dossier actuel
file_name = os.path.join(file_dir, 'Dossier1.1/same.txt')
read_file(file_name)

# Pour accéder au fichier dans le dossier parent du dossier actuel
file_name = os.path.join(file_dir, '../same.txt')
read_file(file_name)

# Pour accéder au fichier dans un dossier frère.
file_name = os.path.join(file_dir, '../Dossier2/same.txt')
file_name = os.path.abspath(os.path.realpath(file_name))
print file_name
read_file(file_name)

0 votes

Pour moi, l'accès au fichier dans le dossier parent du dossier actuel n'a pas fonctionné... les .. sont ajoutés en tant que chaîne de caractères.

0 votes

N'a pas fonctionné sur Windows. Le chemin du fichier est correct mais Python indique "fichier introuvable" et affiche le chemin avec des séparateurs \\

2 votes

Dans Ubuntu et python3, j'ai dû enlever les guillemets de '__file__' donc cela est devenu : fileDir = os.path.dirname(os.path.realpath(__file__))

33voto

Grant Hulegaard Points 536

J'ai créé un compte juste pour pouvoir clarifier une disparité que je pense avoir trouvée dans la réponse originale de Russ.

Pour référence, sa réponse originale était :

import os
script_dir = os.path.dirname(__file__)
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

C'est une excellente réponse car elle essaie de créer de manière dynamique un chemin absolu vers le fichier souhaité.

Cory Mawhorter a remarqué que __file__ est un chemin relatif (c'est aussi le cas sur mon système) et a suggéré d'utiliser os.path.abspath(__file__). os.path.abspath, cependant, renvoie le chemin absolu de votre script actuel (c'est-à-dire /path/to/dir/foobar.py)

Pour utiliser cette méthode (et comment j'ai finalement réussi à le faire fonctionner), vous devez supprimer le nom du script à la fin du chemin :

import os
script_path = os.path.abspath(__file__) # c'est-à-dire /path/to/dir/foobar.py
script_dir = os.path.split(script_path)[0] # c'est-à-dire /path/to/dir/
rel_path = "2091/data.txt"
abs_file_path = os.path.join(script_dir, rel_path)

Le chemin absolu résultant (dans cet exemple) devient : /path/to/dir/2091/data.txt

22 votes

Tu pourrais même combiner les deux approches pour le plus simple os.path.dirname(os.path.abspath(__file__))

3 votes

@LukeTaylor En effet, ce serait mieux que d'essayer de reproduire la fonctionnalité os.path.dirname vous-même comme je l'ai fait dans ma réponse l'année dernière.

24voto

Wilduck Points 5116

Cela dépend du système d'exploitation que vous utilisez. Si vous voulez une solution compatible à la fois avec Windows et *nix quelque chose comme :

from os import path

file_path = path.relpath("2091/data.txt")
with open(file_path) as f:

devrait bien fonctionner.

Le module path est capable de formater un chemin pour n'importe quel système d'exploitation sur lequel il s'exécute. De plus, python gère très bien les chemins relatifs, tant que vous avez les autorisations correctes.

Éditer:

Comme mentionné par kindall dans les commentaires, python peut convertir entre les chemins de style unix et de style windows de toute façon, donc un code encore plus simple fonctionnera :

with open("2091/data/txt") as f:

Cela étant dit, le module path a toujours quelques fonctions utiles.

5 votes

relchemin() convertit un chemin d'accès en un chemin relatif. Étant donné qu'il s'agit déjà d'un chemin relatif, il ne fera rien.

0 votes

Cela le convertira d'un chemin de style Unix en un chemin de style Windows si nécessaire. Y a-t-il une autre fonction dans le module os.path qui serait un meilleur choix?

1 votes

Windows fonctionnera déjà bien avec un chemin de style UNIX. Au moins la série basée sur NT le fera (2000, XP, Vista, 7). Aucune conversion n'est nécessaire.

22voto

Ângelo Polotto Points 562

J'ai passé beaucoup de temps à découvrir pourquoi mon code ne pouvait pas trouver mon fichier en exécutant Python 3 sur le système Windows. J'ai donc ajouté un point devant / et tout a fonctionné correctement :

import os

script_dir = os.path.dirname(__file__)
file_path = os.path.join(script_dir, './output03.txt')
print(file_path)
fptr = open(file_path, 'w')

1 votes

Mieux : chemin_fichier = os.path.join(script_dir, 'output03.txt')

1 votes

J'ai essayé sur le système d'exploitation Windows, mais je n'ai pas réussi.

0 votes

Intéressant - pouvez-vous imprimer script_dir? Puis le convertir en un chemin absolu comme dans script_dir = os.path.abspath(os.path.dirname(__file__))

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