下面的代码将不会连接,在调试时,命令不存储整个路径,而只存储最后一个条目。

os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')

当我测试这个时,它只存储/new_sandbox/部分的代码。


当前回答

os.path.join("a", *"/b".split(os.sep))
'a/b'

更完整的版本:

import os

def join (p, f, sep = os.sep):
    f = os.path.normpath(f)
    if p == "":
        return (f);
    else:
        p = os.path.normpath(p)
        return (os.path.join(p, *f.split(os.sep)))

def test (p, f, sep = os.sep):
    print("os.path.join({}, {}) => {}".format(p, f, os.path.join(p, f)))
    print("        join({}, {}) => {}".format(p, f, join(p, f, sep)))

if __name__ == "__main__":
    # /a/b/c for all
    test("\\a\\b", "\\c", "\\") # optionally pass in the sep you are using locally
    test("/a/b", "/c", "/")
    test("/a/b", "c")
    test("/a/b/", "c")
    test("", "/c")
    test("", "c")

其他回答

为了帮助理解为什么这种令人惊讶的行为并不完全可怕,考虑一个接受配置文件名作为参数的应用程序:

config_root = "/etc/myapp.conf/"
file_name = os.path.join(config_root, sys.argv[1])

如果应用程序以以下方式执行:

$ myapp foo.conf

将使用配置文件/etc/myapp.conf/foo.conf。

但是考虑一下如果应用程序被调用时会发生什么:

$ myapp /some/path/bar.conf

然后myapp应该使用/some/path/bar.conf的配置文件(而不是/etc/myapp.conf/some/path/bar.conf或类似文件)。

这可能不是很好,但我相信这是绝对路径行为的动机。

对于已有连接的字符串,尝试split("/")和*的组合。

import os

home = '/home/build/test/sandboxes/'
todaystr = '042118'
new = '/new_sandbox/'

os.path.join(*home.split("/"), todaystr, *new.split("/"))

它是如何工作的…

Split("/")将现有路径转换为列表:[",'home', 'build', 'test', 'sandboxes', "]

*在列表前面列出列表的每一项自己的参数

我建议从第二个和下面的字符串中剥离字符串os.path。Sep,防止它们被解释为绝对路径:

first_path_str = '/home/build/test/sandboxes/'
original_other_path_to_append_ls = [todaystr, '/new_sandbox/']
other_path_to_append_ls = [
    i_path.strip(os.path.sep) for i_path in original_other_path_to_append_ls
]
output_path = os.path.join(first_path_str, *other_path_to_append_ls)

只使用new_sandbox试试

os.path.join('/home/build/test/sandboxes/', todaystr, 'new_sandbox')

请参考下面的代码片段来理解os.path。加入(a, b)

a = '/home/user.name/foo/'
b = '/bar/file_name.extension'

print(os.path.join(a, b))
>>> /bar/file_name.extension

OR

a = '/home/user.name/foo'
b = '/bar/file_name.extension'
print(os.path.join(a, b))
>>> /bar/file_name.extension

但是,当

a = '/home/user.name/foo/'
b = 'bar/file_name.extension'

print(os.path.join(a, b))
>>> /bar/file_name.extension

OR

a = '/home/user.name/foo'
b = 'bar/file_name.extension'
print(os.path.join(a, b))
>>> /home/user.name/foo/bar/file_name.extension