os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/')
当我测试此命令时,它仅存储
/new_sandbox/
部分的代码。#1 楼
后面的字符串不应以斜杠开头。如果它们以斜杠开头,则它们被视为“绝对路径”,并且它们之前的所有内容都将被丢弃。在Python文档中引用
os.path.join
:如果组件是绝对路径,则所有先前的组件都将被丢弃,并且连接将从绝对路径组件继续。
在Windows上请注意,与驱动器号有关的行为似乎与早期的Python版本相比已发生变化:
在Windows上,遇到绝对路径组件(例如
r'\foo'
)时,不会重置驱动器号。如果组件包含驱动器号,则会丢弃所有先前的组件,并重置驱动器号。请注意,由于每个驱动器都有一个当前目录,因此os.path.join("c:", "foo")
代表相对于驱动器C:
(c:foo
)上当前目录的路径,而不是c:\foo
。#2 楼
os.path.join()
的思想是使您的程序跨平台(linux / windows / etc)。即使有一个斜杠也会破坏它。
所以这仅在使用时有意义带有某种参考点,例如
os.environ['HOME']
或os.path.dirname(__file__)
。#3 楼
os.path.join()
可以与os.path.sep
结合使用,以创建绝对路径而不是相对路径。os.path.join(os.path.sep, 'home','build','test','sandboxes',todaystr,'new_sandbox')
评论
使用os.path.sep作为构建绝对路径的第一个元素比这里的其他答案要好!使用os.path而不是基本的str方法的全部目的是避免编写/。将每个子目录作为新参数并删除所有斜杠也很好。最好检查一下今天是否没有以斜杠开头! ;)
– snooze92
2014年1月23日在8:59
这也适用于Windows(python 2.7.6)。它不干扰“ C:\”,并加入了子目录。
– rickfoosusa
2015年2月2日在21:22
#4 楼
除了引用根目录时,不要在路径组件的开头使用正斜杠:os.path.join('/home/build/test/sandboxes', todaystr, 'new_sandbox')
另请参见:http://docs.python.org/ library / os.path.html#os.path.join
#5 楼
为了帮助理解为什么这种令人惊讶的行为并不完全可怕,请考虑一个将配置文件名作为参数的应用程序: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
或类似的文件)。可能不是很好,但是我相信这是为了绝对路径行为。
评论
谢谢!在阅读您的答案之前,我一直讨厌这种行为!它记录在docs.python.org/3.5/library/os.path.html#os.path.join中,但没有动机。
– Eli_B
17年9月7日在11:59
这一刻,当您确切需要解决方案时,许多人认为这很糟糕。
– Ashrasmun
19年9月4日在20:33
要不同意,这是完全可怕的。在这种情况下,您不应使用朴素的sys.argv输入来确定是否在config_root之前添加。所有os.path.join应该与联接文件路径元素有关。
–user5359531
20年9月1日于20:53
#6 楼
这是因为您的'/new_sandbox/'
以/
开头,因此被认为是相对于根目录的。卸下前导/
。#7 楼
尝试结合使用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', '']
列表前面的
*
将列表中的每个项目分解成自己的参数评论
这将其变成相对路径而不是绝对路径
–user5359531
20年9月1日21:00
#8 楼
为了使您的功能更易于移植,请按以下方式使用它:os.path.join(os.sep, 'home', 'build', 'test', 'sandboxes', todaystr, 'new_sandbox')
或
os.path.join(os.environ.get("HOME"), 'test', 'sandboxes', todaystr, 'new_sandbox')
#9 楼
仅尝试使用new_sandbox
os.path.join('/home/build/test/sandboxes/', todaystr, 'new_sandbox')
#10 楼
这样做,没有太多的斜杠root="/home"
os.path.join(root,"build","test","sandboxes",todaystr,"new_sandbox")
#11 楼
请注意,如果您使用os.path.join()
来包含已经包含点的扩展名,则类似的问题也会咬您,使用os.path.splitext()
时,扩展名会自动出现。在此示例中:即使extension
可能是.jpg
,您最终还是得到一个名为“ foobar”的文件夹,而不是一个名为“ foobar.jpg”的文件。为避免这种情况,您需要单独添加扩展名:components = os.path.splitext(filename)
prefix = components[0]
extension = components[1]
return os.path.join("avatars", instance.username, prefix, extension)
#12 楼
您可以strip
'/'
:>>> os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/'.strip('/'))
'/home/build/test/sandboxes/04122019/new_sandbox'
#13 楼
我建议从第二个及以下字符串中删除字符串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)
#14 楼
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")
评论
如果os.sep实际上是“ \”怎么办?然后,您的第一个示例变为os.path.join(“ a”,*“ / b” .split(“ \\”)),产生“ / b” ...我怀疑这是预期的结果。
– NichtJens
20-5-16在22:13
更新-我想您必须给出提示,因为您在本地使用的路径sep与运行的操作系统无关
–尼尔·麦吉尔(Neil McGill)
20年5月17日在1:54
是。另一种选择是,可以在两个常用选项上分开使用……但是其他一些操作系统可以提供第三个。
– NichtJens
20-05-17在9:30
评论
-1:任何字符串都不应包含“ /”。 os.path.join的一个重点是防止在路径中放置任何斜线。
– S.Lott
09-12-22在12:29
当然,str.join()的问题在于它不会消除双斜杠。我认为这是使用os.path.join的人们的主要目的。例如'/'.join(['/etc/','/ conf'])导致三个斜杠:'/ etc /// conf'
– Dustin Rasener
2012年7月31日14:03
@DustinRasener您可以使用os.path.normpath来实现该目标。
–加雷斯·拉蒂(Gareth Latty)
2012-10-28 17:48
不知道人们为什么对os.path.join行为感到沮丧。在其他语言中,等效的路径连接库/方法的行为完全相同。更安全,更有意义。
–唐·奇德尔(Don Cheadle)
2014年12月4日在17:41
这令人沮丧,因为它是隐式魔术,这与“显式优于隐式”的基本启发式相反。是的。语言设计师可能会认为他们了解得更多,但是存在明显且明显安全的理由,偶尔需要这样做。现在我们不能。这就是为什么我们不能拥有美好的事物。
– Cecil咖喱
15年8月18日在5:54