Comment obtenir un chemin de fichier absolu en Python

726

Étant donné un chemin tel que "mydir/myfile.txt", comment puis-je trouver le chemin absolu du fichier par rapport au répertoire de travail actuel en Python? Par exemple, sous Windows, je pourrais me retrouver avec:

"C:/example/cwd/mydir/myfile.txt"
izb
la source
2
Question similaire: stackoverflow.com/questions/7165749/…
Raj

Réponses:

1057
>>> import os
>>> os.path.abspath("mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'

Fonctionne également s'il s'agit déjà d'un chemin absolu:

>>> import os
>>> os.path.abspath("C:/example/cwd/mydir/myfile.txt")
'C:/example/cwd/mydir/myfile.txt'
sherbang
la source
29
Remarque: Sur la plupart des plates - formes, cela équivaut à appeler la fonction normpath()comme suit: normpath(join(os.getcwd(), path)). Donc, si mydir/myfile.txtce n'est pas le cas os.getcwd(), le chemin absolu n'est pas le vrai chemin .
coanor
32
@coanor? Sans racine explicite, se mydir/myfile.txtréfère implicitement à un chemin à l'intérieur du répertoire de travail actuel comme étant donc équivalent à ./mydir/myfile.txt. Ce n'est peut-être pas le chemin que vous aviez l'intention de saisir, mais cela semble être l'interprétation correcte du chemin pour autant que je sache. Pourriez-vous élaborer?
jpmc26
2
@ jpmc26 Je ne suis pas exactement coanor, mais je dirais que (contrairement à ce que je supposais), il n'y a pas de lien entre l'argument de la abspathfonction et un vrai fichier. Vous pouvez donner n'importe quel nom de fichier inexistant et les hiérarchies de répertoires sont correctes et abspath résoudra simplement les bits du chemin (y compris l' ..élément " " du répertoire parent ) et renverra une chaîne. Ceci est juste une chaîne calculée à partir du répertoire courant; toute corrélation avec un fichier réel est accidentelle, semble-t-il. Essayez os.path.abspath("/wow/junk/../blha/hooey"). Ça marche.
Mike S
2
@MikeS Je ne sais vraiment pas pourquoi ce comportement serait inattendu. C'est un chemin absolu , pas un fichier ou un répertoire absolu. Si vous voulez un contrôle d'existence, appelez os.path.exists. Au contraire, des systèmes comme PowerShell qui insistent sur le chemin existant avec la fonction de résolution de chemin standard sont pénibles à utiliser.
jpmc26
1
@ jpmc26 Supposer qu'un chemin n'est qu'une chaîne qui ressemble à un nom de chemin n'est pas clair du tout, et va à l'encontre de la façon dont je pense et parle des noms de chemin depuis de nombreuses années. Je cite les documents Python 3 pour abspath: "Retourne une version absolutisée normalisée du chemin d' accès ." Pas une "... version du chemin de chaîne ". Un nom de chemin, tel que défini par Posix, est "une chaîne utilisée pour identifier un fichier". Les documents Python sont explicites sur : "le système de fichiers n'est pas accessible pour confirmer l'existence ou la nature de ". Si l'argument ici est évident, pourquoi être explicite ? relpathpathrelpath
Mike S
77

Vous pouvez utiliser la nouvelle bibliothèque Python 3.4 pathlib. (Vous pouvez également l'obtenir pour Python 2.6 ou 2.7 en utilisant pip install pathlib.) Les auteurs ont écrit : "Le but de cette bibliothèque est de fournir une hiérarchie simple de classes pour gérer les chemins du système de fichiers et les opérations courantes que les utilisateurs effectuent dessus."

Pour obtenir un chemin absolu dans Windows:

>>> from pathlib import Path
>>> p = Path("pythonw.exe").resolve()
>>> p
WindowsPath('C:/Python27/pythonw.exe')
>>> str(p)
'C:\\Python27\\pythonw.exe'

Ou sous UNIX:

>>> from pathlib import Path
>>> p = Path("python3.4").resolve()
>>> p
PosixPath('/opt/python3/bin/python3.4')
>>> str(p)
'/opt/python3/bin/python3.4'

Les documents sont ici: https://docs.python.org/3/library/pathlib.html

twasbrillig
la source
4
Très utile. L'utilisation os.path.abspath()m'a donné une erreur :, l' AttributeError: 'NoneType' object has no attribute 'startswith'utilisation Path().resolve()n'a pas le même chemin de fichier relatif. (Linux et Python3.4)
NuclearPeon
23

Mieux encore, installez le module (trouvé sur PyPI), il encapsule toutes les os.pathfonctions et autres fonctions associées dans des méthodes sur un objet qui peut être utilisé partout où des chaînes sont utilisées:

>>> from path import path
>>> path('mydir/myfile.txt').abspath()
'C:\\example\\cwd\\mydir\\myfile.txt'
>>>
À M
la source
2
Dommage qu'ils n'aient jamais obtenu un module d'abstraction de nom de fichier approprié dans le stdlib.
Torsten Marek
1
@Torsten Marek: c'est une omission douloureuse et de longue date.
flow le
4
Ils ont maintenant pour Python 3.4: pathlib. Voir ma réponse dans ce fil.
twasbrillig
Il y a des yypos dans cette réponse. Il devrait être from path import PathalorsPath('mydir/myfile.txt').abspath()
frakman1
Il n'y a pas de faute de frappe, vous utilisiez peut-être un pathmodule différent . Le module lié utilise une classe nommée path.
Tom
10

Mise à jour pour Python 3.4+ pathlibqui répond réellement à la question:

from pathlib import Path

relative = Path("mydir/myfile.txt")
absolute = relative.absolute()  # absolute is a Path object

Si vous n'avez besoin que d'une chaîne temporaire, gardez à l'esprit que vous pouvez utiliser des Pathobjets avec toutes les fonctions pertinentes dans os.path, y compris bien sûr abspath:

from os.path import abspath

absolute = abspath(relative)  # absolute is a str object
Physicien fou
la source
9
import os
os.path.abspath(os.path.expanduser(os.path.expandvars(PathNameString)))

Notez que cela expanduserest nécessaire (sous Unix) dans le cas où l'expression donnée pour le nom et l'emplacement du fichier (ou répertoire) peut contenir un interligne ~/(le tilde fait référence au répertoire personnel de l'utilisateur) et expandvarsprend en charge toutes les autres variables d'environnement (comme $HOME).

benjimin
la source
6

Cela obtient toujours le bon nom de fichier du script actuel, même lorsqu'il est appelé à partir d'un autre script. Il est particulièrement utile lors de l'utilisation subprocess.

import sys,os

filename = sys.argv[0]

à partir de là, vous pouvez obtenir le chemin complet du script avec:

>>> os.path.abspath(filename)
'/foo/bar/script.py'

Il facilite également la navigation dans les dossiers en ajoutant simplement /..autant de fois que vous le souhaitez pour remonter dans la hiérarchie des répertoires.

Pour obtenir le cwd:

>>> os.path.abspath(filename+"/..")
'/foo/bar'

Pour le chemin parent:

>>> os.path.abspath(filename+"/../..")
'/foo'

En combinant "/.."avec d'autres noms de fichiers, vous pouvez accéder à n'importe quel fichier du système.

Lucas Azevedo
la source
Ce n'est pas ce qui était demandé. Ils ont demandé un chemin par rapport au répertoire de travail actuel, qui n'est pas la même chose que le répertoire de script, bien qu'ils puissent parfois avoir la même valeur.
L'élémental de la création
3

Le module osfournit un moyen de trouver le chemin abs.

MAIS la plupart des chemins sous Linux commencent par ~(tilde), ce qui ne donne pas un résultat satisfaisant.

afin que vous puissiez l'utiliser srblibpour cela.

>>> import os
>>> os.path.abspath('~/hello/world')
'/home/srb/Desktop/~/hello/world'
>>> from srblib import abs_path
>>> abs_path('~/hello/world')
'/home/srb/hello/world'

installez-le en utilisant python3 -m pip install srblib

https://pypi.org/project/srblib/

srbcheema1
la source
1

Je préfère utiliser glob

voici comment répertorier tous les types de fichiers dans votre dossier actuel:

import glob
for x in glob.glob():
    print(x)

voici comment lister tous (par exemple) les fichiers .txt de votre dossier actuel:

import glob
for x in glob.glob('*.txt'):
    print(x)

voici comment lister tous les types de fichiers dans un répertoire choisi:

import glob
for x in glob.glob('C:/example/hi/hello/'):
    print(x)

j'espère que cela vous a aidé

F. Taylor
la source
2
Vous semblez répondre à une autre question. Ce n'était pas "Comment obtenir un chemin?", Mais "un chemin absolu". On pourrait appliquer la bonne réponse ( os.path.abspath()) à tout chemin relatif globprévu pour vos deux premiers cas ...
NichtJens
1

si vous êtes sur un mac

import os
upload_folder = os.path.abspath("static/img/users")

cela vous donnera un chemin complet:

print(upload_folder)

affichera le chemin suivant:

>>>/Users/myUsername/PycharmProjects/OBS/static/img/user
chikwapuro
la source
1

Dans le cas où quelqu'un utilise python et linux et cherche le chemin complet du fichier:

>>> path=os.popen("readlink -f file").read()
>>> print path
abs/path/to/file
BND
la source