在Python中适用于任何平台的Unix路径是什么?

10

在 Python 程序中,所有路径都可以使用 ".."(表示上一级目录)和 /(用于分隔路径组件),并且仍然可以在任何平台上工作吗?

一方面,在文档中我从未看到过这样的声明(可能我错过了),而 os 和 os.path 模块提供了处理路径的跨平台方法(os.pardir、os.path.join 等),这让我认为它们存在是有原因的。

另一方面,你可以在 StackOverflow 上读到,“../path/to/file” 在所有平台上都可以使用…

那么,为了可移植性,应该始终使用 os.pardir、os.path.join 等方法,还是 Unix 路径名总是安全的(可能存在字符编码问题)?或者说在 Windows、OS X 和 Linux 下“几乎总是”安全的?


4
以前在 Windows 上从未遇到过问题。 - jldupont
7个回答

11

我从未在使用 .. 上遇到任何问题,不过把它转换为绝对路径可能是个好主意,可以使用os.path.abspath。其次,我建议尽可能始终使用 os.path.join。在连接路径方面有很多边角情况(除了可移植性问题),最好不必担心它们。例如:

>>> '/foo/bar/' + 'qux'
'/foo/bar/qux'
>>> '/foo/bar' + 'qux'
'/foo/barqux'
>>> from os.path import join
>>> join('/foo/bar/', 'qux')
'/foo/bar/qux'
>>> join('/foo/bar', 'qux')
'/foo/bar/qux'

如果你在一些偏僻的平台上使用..可能会遇到问题,但我无法列举出任何一个(Windows、*nix和OS X都支持该表示法)。


6
"几乎总是安全"是正确的。您关心的所有平台今天可能都可以正常工作,我认为它们不会很快改变自己的惯例。然而,Python非常便携,并且在许多不同于通常平台的操作系统上运行。如果平台有不同的要求,os模块的原因就是帮助平滑过渡。
你有没有不使用os函数的好理由?os.pardir是自我记录的,而".."则不是,os.pardir可能更容易进行grep搜索。
这里是一些来自Python 1.6文档的内容,当时Mac对于所有内容都不同:

根据我们所在的系统,用于Mac、DOS、NT或Posix的操作系统例程。

这将导出以下内容: - 来自posix、nt、dos、os2、mac或ce的所有函数,例如unlink、stat等。 - os.path是posixpath、ntpath、macpath或dospath模块之一 - os.name是'posix'、'nt'、'dos'、'os2'、'mac'或'ce' - os.curdir是表示当前目录('.'或':')的字符串 - os.pardir是表示父目录('..'或'::')的字符串 - os.sep是路径名分隔符('/'或':'或'\') - os.altsep是替代路径名分隔符(无或'/') - os.pathsep是$PATH等中使用的组件分隔符 - os.linesep是文本文件中的行分隔符(''或''或'') - os.defpath是可执行文件的默认搜索路径

导入并使用'os'的程序更有可能在不同平台之间进行移植。当然,它们必须仅使用所有平台都定义的函数(例如unlink和opendir),并将所有路径名操作留给os.path(例如split和join)。

"

我考虑绕过os.path等模块的原因是,使用"../dir1/dir2/dir3/file"比使用os.path.join(os.pardir, ['dir1', 'dir2', 'dir3', 'file'])更简单明了! - Eric O. Lebigot
@EOL 我想不出有太多需要那样做的真实程序。也许将这样的路径移动到配置文件中会更合理。 - John La Rooy
@gnibbler 我的程序分析了数千组数据,并将结果存储在传统位置,其中目录名称是从每个数据集的“名称”计算出来的。但是,os.path.join(os.pardir, ...)几乎与直接路径编码一样短。 - Eric O. Lebigot
Python在Windows上接受“/”作为路径分隔符这一事实的文档放在哪里了?我找不到它... - Eric O. Lebigot
1
@EOL,这不是Python - 它在Windows API中。"注意:Windows API中的文件I/O函数将“/”转换为“\”作为将名称转换为NT样式名称的一部分,除非使用以下部分中详细说明的“\?\”前缀。" - John La Rooy
谢谢!我希望Python文档说Python遵循这个约定-原则上它不必这样做,尽管不遵循这个约定会使事情变得更加复杂而没有好的理由。:) 强调一般os.sepos.join()等功能让我想知道/是否必须在Windows上工作。现在我明白了,这些设施主要是为更晦涩的操作系统(非Windows,非Unix/Linux/OS X)服务的。 - Eric O. Lebigot

3

在Python中,使用/符号总是有效的。如果你想在子shell中执行命令,你需要了解操作系统的惯例。

myprog = "/path/to/my/program"
os.system([myprog, "-n"])                           # 1
os.system([myprog, "C:/input/file/to/myprog"])      # 2

第一条命令很可能按预期工作。
如果myprog是Windows命令并且期望解析其命令行参数以获取Windows文件名,则第二条命令可能无法正常工作。


1
只是一点小建议 - 永远不要使用 os.system 来运行程序。它需要一个字符串(而不是像你使用的列表),并且不必要地调用了一个 shell。相反,请使用 subprocess 模块。 - nosklo

3

Windows使用/作为路径分隔符。Unix文件名和Windows文件名之间唯一的不兼容之处是:

  • 文件名中允许的字符
  • 特殊名称
  • 大小写敏感性

在前两个方面上,Windows更加严格(即它有更多被禁止的字符和更多的特殊名称),而Unix通常区分大小写。这里有一些答案列出了这些字符和名称。我会看看是否能找到它们。

现在,如果您的开发环境带有创建或操作路径的功能,您应该使用它,因为它存在的原因就是为了方便。特别是考虑到除了Windows和Unix之外还有很多其他平台。

回答您的第一个问题,是的,../dir/file将起作用,除非它们遇到了上述提到的不兼容性。


不要忘记大小写敏感性的差异。 - Michael Mior

3

它适用于Windows,因此如果您将“任何平台”定义为Unix和Windows,则可以正常使用。

另一方面,Python还可以在VMS、RISC OS和其他使用完全不同文件名约定的奇怪平台上运行。然而,盲目地尝试在VMS上运行你的应用程序可能有点傻 - “过早的可移植性是某些相对较小的问题的根源”。

我喜欢使用os.path函数,因为它们非常适合表达意图 - 而不仅仅是字符串连接,这可能是为了任何一个无法计数的目的而完成的,它非常明确地读作路径操作。


1

OS/X和Linux都兼容Unix,因此根据定义,它们使用您在问题开头提供的格式。Windows除了“\”之外还允许“/”,以便程序可以与Xenix互换,这是微软很久以前尝试的一种Unix变体,并且这种兼容性一直延续到现在。 因此,它也可以工作。

我不知道Python已经移植到多少其他平台,我不能代表它们发言。


0

正如其他人所说,斜杠在所有情况下都可以使用,但最好创建路径段的列表并使用os.path.join()连接它们。


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