如何在Python中获取/设置逻辑目录路径

10
在Python中,是否可以获取或设置逻辑目录(而不是绝对路径)?
例如,如果我有以下代码:
/real/path/to/dir

而我拥有

/linked/path/to/dir

链接到相同的目录。

使用 os.getcwd 和 os.chdir 将始终使用绝对路径。

>>> import os
>>> os.chdir('/linked/path/to/dir')
>>> print os.getcwd()
/real/path/to/dir

我发现唯一避免这个问题的方法就是在另一个进程中启动'pwd'并读取输出。但是,只有在第一次调用os.chdir之前才有效。

2个回答

13

底层操作系统/ shell向python报告实际路径。

因此,由于os.getcwd()是对C库getcwd()函数的封装调用,所以确实没有绕过它的方法。

有一些解决方法与你已经知道的其中一种类似,即启动pwd

另一个方法涉及使用os.environ['PWD']。如果设置了该环境变量,则可以创建一些能够遵循它的getcwd函数。

下面的解决方案结合了两种方法:

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.

1
这对我也有用:
import os
os.popen('pwd').read().strip('\n')

这是一个Python Shell演示示例:

>>> 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'

获取环境变量PWD并不总是有效,因此我使用popen方法。干杯!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接