我想在 python 中构造一个绝对路径,同时保持对诸如路径分隔符之类的东西的忽视。
edit0: 例如,我的文件系统
/etc/init.d
(或 w32 上的 C:\etc\init.d
)的根目录中有一个目录,我只想从元素 etc
和 init.d
(在 w32 上,我可能还需要一个磁盘 ID,例如 C:
)
为了不必担心路径分隔符,
os.join.path()
显然是首选工具。但似乎这只会创建relative路径:
print("MYPATH: %s" % (os.path.join('etc', 'init.d'),)
MYPATH: etc/init.d
添加虚拟的第一个元素(例如
''
)没有任何帮助:
print("MYPATH: %s" % (os.path.join('', 'etc', 'init.d'),)
MYPATH: etc/init.d
使第一个元素绝对化显然有帮助,但这违背了使用
os.path.join()
的想法
print("MYPATH: %s" % (os.path.join('/etc', 'init.d'),)
MYPATH: /etc/init.d
edit1:使用
os.path.abspath()
只会尝试将相对路径转换为绝对路径。
例如考虑在工作目录中运行以下命令/home/foo
:
print("MYPATH: %s" % (os.path.abspath(os.path.join('etc', 'init.d')),)
MYPATH: /home/foo/etc/init.d
那么,“root”路径的标准跨平台方法是什么?
root = ??? # <--
print("MYPATH: %s" % (os.path.join(root, 'etc', 'init.d'),)
MYPATH: /etc/init.d
edit2:问题实际上归结为:由于
/etc/init.d
中的前导斜杠使该路径成为绝对路径,有没有办法以编程方式构造此前导斜杠?
(我不想假设前导斜杠表示绝对路径)
使用
os.sep
作为 root 对我有用:
path.join(os.sep, 'python', 'bin')
Linux:
/python/bin
Windows:
\python\bin
添加
path.abspath()
也将为您提供 Windows 上的驱动器号,并且仍然与 Linux 兼容:
path.abspath(path.join(os.sep, 'python', 'bin'))
Linux:
/python/bin
Windows:
C:\python\bin
我认为你可以使用
os.path.normpath
。这是我在 Windows 上得到的结果:
>>> os.path.normpath("/etc/init.d")
'\\etc\\init.d'
我不确定对驱动器前缀的正确做法是什么,但我认为将其保留意味着“继续使用我现在所在的驱动器”,这可能就是您想要的。也许更熟悉 Windows 的人可以澄清一下?
所以我想出的解决方案是通过跟随给定文件到它的根来构建文件系统的根:
def getRoot(file=None):
if file is None:
file='.'
me=os.path.abspath(file)
drive,path=os.path.splitdrive(me)
while 1:
path,folder=os.path.split(path)
if not folder:
break
return drive+path
os.path.join(getRoot(), 'etc', 'init.d')
因此您可以检查正在运行的操作系统 通过 sys.platfrom
在 Windows 上
>>> sys.platform
'win32'
在Linux上
>>> sys.platform
'linux2'
然后
if sys.platform == 'win32':
ROOT = os.path.splitdrive(os.path.abspath('.'))[0]
elif sys.platform == 'linux2':
ROOT = os.sep
请注意,“linux2”可能不涵盖所有 Linux 发行版
来自标准库中的 python 3.4
pathlib
。你可以这样做:
import pathlib
pathlib.Path('/') / 'etc' / 'init.d'
您可以在 Windows 上检查:
import pathlib
import os
path = pathlib.Path('/') / 'Windows'
print(os.path.exists(path)) >>> true
此路径与所有 Windows、Linux 和其他操作系统兼容..
您可以尝试使用
os.path.splitdrive
获取驱动器/文件系统的名称,然后将其与您的 foo
字符串连接起来。
http://docs.python.org/2/library/os.path.html#os.path.splitdrive
类似(未经测试!)
(drive, tail) = os.path.splitdrive(os.getcwd())
os.path.join(drive, 'foo')
应该可以解决问题。