关于python:os.path.join-我可以在Windows和Cygwin之间获得一致性吗?

os.path.join - can I get consistency between Windows and Cygwin?

我非常希望有一组文件名组件,这些文件名组件将为我在Windows和Cygwin上提供一致且"漂亮"的文件名。这是我尝试过的:

1
2
3
4
  Input                                Windows      Cygwin
1 os.path.join('c:', 'foo', 'bar')     c:foo\\bar    c:/foo/bar
2 os.path.join('c:\\\', 'foo', 'bar')   c:\\foo\\bar   c:\\/foo/bar
3 os.path.join('
c:/', 'foo', 'bar')    c:/foo\\bar   c:/foo/bar

1不是我在Windows上想要的,我确实想要一个绝对路径,而不是相对于当前目录的路径。

2和3都可以,但是(我在此定义)不是"好看的",因为它们在一个平台或另一个平台上混合了正斜杠和反斜杠。如果可以避免的话,我的错误和日志消息将更具可读性。

选项4是为自己定义一个driveroot变量,该变量等于Windows上的c:\\和Cygwin上的/cygdrive/c。或带驱动器号并返回的函数。但我也希望避免在这两者之间使用跨平台的特殊情况。

我是否可以拥有所有想要的东西(加入相同的路径组件,以得到在两个平台上都引用相同的绝对路径,并且在两个平台上都不混合路径分隔符的结果)?还是我必须在某个地方妥协?

[编辑:如果有帮助,主要用例是c:\\foo是我在配置时知道的路径,而bar(及其他组件)将在以后计算。所以我的实际代码目前看起来像这样:

1
2
3
4
5
dir = os.path.join('c:\\\', 'foo')

# some time later

os.path.join(dir, '
bar')

这使用的是选项2,这会导致Windows中文件名的报告"不错",而Cygwin中文件名的报告"不好"。如果可能的话,我想避免的是:

1
2
3
4
if this_is_cygwin():
    dir = '/cygdrive/c/foo'
else:
    dir = 'c:\\\\foo'

]


编辑:大卫指出,我对Windows上的"当前目录"的理解是错误的。抱歉。但是,尝试使用os.path.abspath获得漂亮的漂亮路径,或者如果不需要绝对路径,则使用os.path.normpath

在方法1中,

1
os.path.join('c:', 'foo', 'bar')

输出c:foo\\bar是正确的。这意味着c:上当前目录下的路径foo\\bar与根目录不同。 os.path.join完全按照您的指示进行操作,即采用c:(驱动器c上的当前目录)并向其中添加一些额外的位。

在方法2中,

1
os.path.join(r'c:\', 'foo', 'bar')

Cygwin的输出是正确的,因为在Cygwin中,c:\\不是驱动器的根目录。

您需要的是os.abspath函数。这将为您提供给它的路径的绝对标准化版本。

但是:在Cygwin和Windows上不会获得相同的字符串。希望您不要这样。


在工作中,我必须处理不带Cygiwn的Windows的相当随机的组合,带非Cygwin Python的Cygwin,带Cygwin Python的Cygwin和Unix。我还没有找到一种对付我特别引以为豪的方法,但是到目前为止,我发现最讨厌的方法是在Windows上始终使用Cygwin所谓的"混合样式"路径。这是Windows样式的路径,但是使用正斜杠而不是反斜杠。例如c:/foo/bar.txt。它还避免了很多陷阱,例如Cygwin bash shell将""视为转义字符。可悲的是,这意味着错过了许多Python的内置路径操作实用程序,并且很难进行操作。

我无法访问在ATM上装有Python和Cygwin的计算机,因此无法测试下面的代码段。如有任何错误,我深表歉意...

1
2
3
4
5
    #Combine a path
    path = '/'.join([ 'c:', 'foo', 'bar'])

    #Split it back apart
    pieces = path.split('/')

如有疑问,请尝试调用Cygwin的cygpath实用程序。 Cygwin中出现了许多奇怪的边缘情况,例如/ cygdrive / d / == d:\而/cygdrive/d/../../ == c:\ cygwin(或任何您拥有的地方) Cygwin已安装)。还请记住,反斜杠在Unix样式路径(例如/ cygdrive / c / Documents \和\ Settings)中用作转义字符。 Cygpath在处理这些问题上做得令人吃惊,如果没有可用的工具,通常可以假设您的怪异案例不存在。

[/cc]

如果通过Windows样式路径传递某些Windows命令,则使它们感到困惑;如果通过Windows或混合样式路径传递某些Cygwin命令,则使它们感到困惑。例如,rsync可能会与" c:/foo/bar.txt"混淆,因为这似乎是您在尝试在名为" c"的远程计算机上指定" /foo/bar.txt"。当您调用这些挑剔的Windows或Cygwin程序之一时,请使用cygpath使它高兴。如果您正在调用一个挑剔的Windows程序而cygpath不可用,请尝试使用贫民窟" winpath = mypath.replace('/','\')"方法。我认为如果您要转换Unix样式路径并且没有Cygwin可能会失败,但是希望如果您没有Cygwin可以在Windows上没有任何Unix样式路径开头...