Comment obtenir / définir le chemin du répertoire logique en python
Question
En python, il est possible d’obtenir ou de définir un répertoire logique (par opposition à un répertoire absolu).
Par exemple, si j'ai:
/real/path/to/dir
et j'ai
/linked/path/to/dir
lié ??au même répertoire.
utiliser os.getcwd et os.chdir utilisera toujours le chemin absolu
>>> import os
>>> os.chdir('/linked/path/to/dir')
>>> print os.getcwd()
/real/path/to/dir
Le seul moyen que j’ai trouvé pour résoudre ce problème est de lancer 'pwd' dans un autre processus et de lire le résultat. Toutefois, cela ne fonctionne que lorsque vous appelez os.chdir pour la première fois.
La solution
Le système / shell opérationnel sous-jacent signale les chemins d'accès réels à python.
Donc, il n'y a vraiment aucun moyen de le contourner, puisque os.getcwd ()
est un appel encapsulé à la fonction C Library getcwd ()
.
Il existe certaines solutions dans l'esprit de celle que vous connaissez déjà et qui lance pwd
.
Une autre solution consisterait à utiliser os.environ ['PWD']
. Si cette variable d’environnement est définie, vous pouvez créer une fonction getcwd
qui la respecte.
La solution ci-dessous combine les deux:
import os
from subprocess import Popen, PIPE
class CwdKeeper(object):
def __init__(self):
self._cwd = os.environ.get("PWD")
if self._cwd is None: # no environment. fall back to calling pwd on shell
self._cwd = Popen('pwd', stdout=PIPE).communicate()[0].strip()
self._os_getcwd = os.getcwd
self._os_chdir = os.chdir
def chdir(self, path):
if not self._cwd:
return self._os_chdir(path)
p = os.path.normpath(os.path.join(self._cwd, path))
result = self._os_chdir(p)
self._cwd = p
os.environ["PWD"] = p
return result
def getcwd(self):
if not self._cwd:
return self._os_getcwd()
return self._cwd
cwd = CwdKeeper()
print cwd.getcwd()
# use only cwd.chdir and cwd.getcwd from now on.
# monkeypatch os if you want:
os.chdir = cwd.chdir
os.getcwd = cwd.getcwd
# now you can use os.chdir and os.getcwd as normal.
Autres conseils
Cela fait aussi l'affaire pour moi:
import os
os.popen('pwd').read().strip('\n')
Voici une démonstration dans un shell python:
>>> import os
>>> os.popen('pwd').read()
'/home/projteam/staging/site/proj\n'
>>> os.popen('pwd').read().strip('\n')
'/home/projteam/staging/site/proj'
>>> # Also works if PWD env var is set
>>> os.getenv('PWD')
'/home/projteam/staging/site/proj'
>>> # This gets actual path, not symlinked path
>>> import subprocess
>>> p = subprocess.Popen('pwd', stdout=subprocess.PIPE)
>>> p.communicate()[0] # returns non-symlink path
'/home/projteam/staging/deploys/20150114-141114/site/proj\n'
Obtenir la variable d’environnement PWD ne fonctionnant pas toujours pour moi, j’utilise la méthode popen. À la vôtre!