126

我可以

>>> os.path.join("c:/","home","foo","bar","some.txt")
'c:/home\\foo\\bar\\some.txt'

但是,当我这样做时

>>> s = "c:/,home,foo,bar,some.txt".split(",")
>>> os.path.join(s)
['c:/', 'home', 'foo', 'bar', 'some.txt']

我在这里想念什么?

4

5 回答 5

232

问题是,os.path.joinlist作为参数,它必须是单独的参数。

这就是*'splat'运算符发挥作用的地方......

我可以

>>> s = "c:/,home,foo,bar,some.txt".split(",")
>>> os.path.join(*s)
'c:/home\\foo\\bar\\some.txt'
于 2013-02-12T06:40:15.950 回答
30

假设join不是那样设计的(正如 ATOzTOA 指出的那样),并且它只需要两个参数,您仍然可以使用内置的reduce

>>> reduce(os.path.join,["c:/","home","foo","bar","some.txt"])
'c:/home\\foo\\bar\\some.txt'

相同的输出,如:

>>> os.path.join(*["c:/","home","foo","bar","some.txt"])
'c:/home\\foo\\bar\\some.txt' 

仅出于完整性和教育原因(以及其他*不起作用的情况)。

Python 3 的提示

reduce已移至functools模块。

于 2013-02-12T10:39:05.550 回答
16

我偶然发现了列表可能为空的情况。在这种情况下:

os.path.join('', *the_list_with_path_components)

注意第一个参数,它不会改变结果。

于 2014-04-17T16:43:56.597 回答
10

这只是方法。你没有错过任何东西。官方文档显示可以使用列表解包来提供几个路径:

s = "c:/,home,foo,bar,some.txt".split(",")
os.path.join(*s)

注意*s只是sin的意思os.path.join(*s)。使用星号将触发列表的解包,这意味着每个列表参数将作为单独的参数提供给函数。

于 2013-02-12T06:44:39.467 回答
2

如果您想从函数式编程的角度来考虑,这也可以被认为是一个简单的 map reduce 操作。

import os
folders = [("home",".vim"),("home","zathura")]
[reduce(lambda x,y: os.path.join(x,y), each, "") for each in folders]

reduce在 Python 2.x 中内置。在 Python 3.x 中,它已移至itertools但是接受的答案更好。

这已在下面回答,但如果您有需要加入的项目列表,请回答。

于 2015-07-06T10:21:31.827 回答