这个问题应该是显而易见的,但我还没有能够解决它。
我需要一个函数,它接受两个参数,每个参数一个文件路径,相对或绝对,并返回一个文件路径,该文件路径是相对于第二个路径(开始)解析的第一个路径(目标)。解析的路径可能是相对于当前目录的,也可能是绝对的(我不在乎)。
这里作为一个尝试的实现,完成了几个文档测试,练习了一些示例用例(并演示了失败的地方)。 A我的源代码存储库中也提供了可运行的脚本 https://svn.jaraco.com/jaraco/python/jaraco.windows/bugs/find_target_path.py,但可能会改变。如果未提供参数,可运行脚本将运行 doctest;如果提供,则将向 findpath 传递一两个参数。
def findpath(target, start=os.path.curdir):
r"""
Find a path from start to target where target is relative to start.
>>> orig_wd = os.getcwd()
>>> os.chdir('c:\\windows') # so we know what the working directory is
>>> findpath('d:\\')
'd:\\'
>>> findpath('d:\\', 'c:\\windows')
'd:\\'
>>> findpath('\\bar', 'd:\\')
'd:\\bar'
>>> findpath('\\bar', 'd:\\foo') # fails with '\\bar'
'd:\\bar'
>>> findpath('bar', 'd:\\foo')
'd:\\foo\\bar'
>>> findpath('bar\\baz', 'd:\\foo')
'd:\\foo\\bar\\baz'
>>> findpath('\\baz', 'd:\\foo\\bar') # fails with '\\baz'
'd:\\baz'
Since we're on the C drive, findpath may be allowed to return
relative paths for targets on the same drive. I use abspath to
confirm that the ultimate target is what we expect.
>>> os.path.abspath(findpath('\\bar'))
'c:\\bar'
>>> os.path.abspath(findpath('bar'))
'c:\\windows\\bar'
>>> findpath('..', 'd:\\foo\\bar')
'd:\\foo'
>>> findpath('..\\bar', 'd:\\foo')
'd:\\bar'
The parent of the root directory is the root directory.
>>> findpath('..', 'd:\\')
'd:\\'
restore the original working directory
>>> os.chdir(orig_wd)
"""
return os.path.normpath(os.path.join(start, target))
从 doctest 中的注释可以看出,当起始指定驱动器号并且目标相对于驱动器的根目录时,此实现会失败。
这带来了几个问题
- 这种行为是 os.path.join 的限制吗?换句话说, os.path.join('d:\foo', '\bar') 应该解析为 'd:\bar' 吗?作为一名 Windows 用户,我倾向于这么认为,但我讨厌认为像 path.join 这样的成熟函数需要进行修改才能处理这个用例。
- 是否有现有目标路径解析器(例如 findpath)的示例可以在所有这些测试用例中工作?
- 如果上述问题的答案为“否”,您将如何实现这一期望的行为?
我同意你的观点:这似乎是 os.path.join 的缺陷。看来您必须单独处理驱动器。此代码通过了您的所有测试:
def findpath(target, start=os.path.curdir):
sdrive, start = os.path.splitdrive(start)
tdrive, target = os.path.splitdrive(target)
rdrive = tdrive or sdrive
return os.path.normpath(os.path.join(rdrive, os.path.join(start, target)))
(是的,我必须嵌套两个 os.path.join 才能让它工作......)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)