2008-09-23 10 views
7

En python, il est possible d'obtenir ou de définir un répertoire logique (par opposition à un répertoire absolu).Comment obtenir/définir le chemin du répertoire logique en python

Par exemple, si je:

/real/path/to/dir 

et je

/linked/path/to/dir 

liés au même répertoire.

utilisant 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 

La seule façon que je l'ai trouvé pour se déplacer du tout est de lancer « passwd » dans un autre processus et lire la sortie . Cependant, cela ne fonctionne que jusqu'à ce que vous appeliez os.chdir pour la première fois.

Répondre

11

Le système/shell opérationnel sous-jacent signale les chemins réels vers python.

Donc, il n'y a vraiment aucun moyen de contourner cela, puisque os.getcwd() est un appel enveloppé à la fonction C Library getcwd().

Il existe certaines solutions de contournement dans l'esprit de celui que vous connaissez déjà qui lance pwd.

Un autre impliquerait l'utilisation de os.environ['PWD']. Si cette variable d'environnement est définie, vous pouvez créer une fonction getcwd qui la respecte.

La solution combine ci-dessous à la fois:

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. 
+0

Merci! getcwd() a besoin d'un argument de soi - autre que cela fonctionne parfaitement! – Moe

+0

ok, corrigé, merci. – nosklo

1

Cela fait aussi l'affaire pour moi:

import os 
os.popen('pwd').read().strip('\n') 

Voici une démonstration en 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 l'environnement la variable PWD ne fonctionnait pas toujours pour moi donc j'utilise la méthode popen. À votre santé!

Questions connexes