web-dev-qa-db-fra.com

Python os.path.join sous Windows

J'essaie d'apprendre le python et je crée un programme qui va générer un script. Je veux utiliser os.path.join, mais je suis assez confus. Selon la docs si je dis:

os.path.join('c:', 'sourcedir')

Je reçois "C:sourcedir". Selon les docs, c'est normal, non?

Mais lorsque j'utilise la commande copytree, Python l'éditera de la manière souhaitée, par exemple:

import shutil
src = os.path.join('c:', 'src')
dst = os.path.join('c:', 'dst')
shutil.copytree(src, dst)

Voici le code d'erreur que je reçois:

 WindowsError: [Erreur 3] Le système ne trouve pas le chemin spécifié: "C: src /*.*" 

Si j'emballe le os.path.join avec os.path.normpath, j'obtiens la même erreur.

Si ce os.path.join ne peut pas être utilisé de cette façon, je suis confus quant à son objectif.

Selon les pages suggérées par Stack Overflow, les barres obliques ne doivent pas être utilisées dans une jointure. C’est exact, je suppose?

73
Frank E.

Windows a un concept de répertoire actuel pour chaque lecteur. A cause de cela, "c:sourcedir" signifie "sourcedir" dans le répertoire C: actuel et vous devrez spécifier un répertoire absolu.

N'importe lequel de ceux-ci devrait fonctionner et donner le même résultat, mais je n'ai pas de Windows VM allumé pour le moment pour vérifier:

"c:/sourcedir"
os.path.join("/", "c:", "sourcedir")
os.path.join("c:/", "sourcedir")
43
Roger Pate

Pour être encore plus pédant, la réponse la plus cohérente avec les documents python serait:

mypath = os.path.join('c:', os.sep, 'sourcedir')

Puisque vous avez également besoin de os.sep pour le chemin racine posix:

mypath = os.path.join(os.sep, 'usr', 'lib')
95
AndreasT

La raison pour laquelle os.path.join('C:', 'src') ne fonctionne pas comme prévu est due à un élément de la documentation auquel vous avez lié:

Notez que sous Windows, car il existe un répertoire en cours pour chaque lecteur, os.path.join ("c:", "foo") représente un chemin relatif au répertoire en cours sur le lecteur C: (c: toto), pas c:\toto.

Comme dit ghostdog, vous voulez probablement mypath=os.path.join('c:\\', 'sourcedir')

11
Smashery

Pour être pédant, il n’est probablement pas bon de coder en dur soit comme séparateur de chemin Peut-être que ce serait mieux?

mypath = os.path.join('c:%s' % os.sep, 'sourcedir')

ou 

mypath = os.path.join('c:' + os.sep, 'sourcedir')
9
Matt Ball

Je dirais que c'est un bogue Python (Windows).

Pourquoi bug? 

Je pense que cette déclaration devrait être True

os.path.join(*os.path.dirname(os.path.abspath(__file__)).split(os.path.sep))==os.path.dirname(os.path.abspath(__file__))

Mais c’est False sur les machines Windows.

4
georg

pour rejoindre un chemin Windows, essayez

mypath=os.path.join('c:\\', 'sourcedir')

fondamentalement, vous devrez échapper à la barre oblique

3
ghostdog74

Pour une solution indépendante du système fonctionnant sous Windows et Linux, quel que soit le chemin d'entrée, vous pouvez utiliser os.path.join(os.sep, rootdir + os.sep, targetdir)

Sur Windows:

>>> os.path.join(os.sep, "C:" + os.sep, "Windows")
'C:\\Windows'

Sous Linux:

>>> os.path.join(os.sep, "usr" + os.sep, "lib")
'/usr/lib'
2
Scott Gigante

Vous avez plusieurs approches possibles pour traiter le chemin sous Windows, des plus codées en dur (comme l’utilisation de littéraux de chaîne bruts ou des barres obliques inverses) aux plus petites. Voici quelques exemples qui fonctionneront comme prévu. Utilisez ce qui correspond le mieux à vos besoins.

In[1]: from os.path import join, isdir

In[2]: from os import sep

In[3]: isdir(join("c:", "\\", "Users"))
Out[3]: True

In[4]: isdir(join("c:", "/", "Users"))
Out[4]: True

In[5]: isdir(join("c:", sep, "Users"))
Out[5]: True
2
Marco Gomez

Consentement avec @ georg-

Je dirais alors pourquoi nous avons besoin du os.path.join_ ___ préférable d'utiliser str.join ou unicode.join par exemple.

sys.path.append('{0}'.join(os.path.dirname(__file__).split(os.path.sep)[0:-1]).format(os.path.sep))
0
SIslam