Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么';t os.path.join()在这种情况下有效吗?_Python_Path - Fatal编程技术网

Python 为什么';t os.path.join()在这种情况下有效吗?

Python 为什么';t os.path.join()在这种情况下有效吗?,python,path,Python,Path,下面的代码将不会加入,调试时,该命令不会存储整个路径,而只存储最后一个条目 os.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/') 当我测试这个时,它只存储代码的/new\u sandbox/部分。后面的字符串不应该以斜杠开头。如果它们以斜线开头,那么它们被视为“绝对路径”,前面的所有内容都被丢弃 引述: 如果组件是绝对路径,则会丢弃所有以前的组件,并从绝对路径组件继续连接 注意:在Windows上,与驱动器

下面的代码将不会加入,调试时,该命令不会存储整个路径,而只存储最后一个条目

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

当我测试这个时,它只存储代码的
/new\u sandbox/
部分。

后面的字符串不应该以斜杠开头。如果它们以斜线开头,那么它们被视为“绝对路径”,前面的所有内容都被丢弃

引述:

如果组件是绝对路径,则会丢弃所有以前的组件,并从绝对路径组件继续连接

注意:在Windows上,与驱动器号相关的行为与早期Python版本相比似乎有所改变:

在Windows上,遇到绝对路径组件(例如,
r'\foo'
)时,不会重置驱动器号。如果某个组件包含驱动器号,则会丢弃以前的所有组件并重置驱动器号。请注意,由于每个驱动器都有一个当前目录,
os.path.join(“c:,“foo”)
表示相对于驱动器
c:
c:foo
)上当前目录的路径,而不是
c:\foo


不要在路径组件的开头使用正斜杠,除非引用根目录:

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

另请参见:

仅尝试使用
新沙盒

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

这是因为您的
'/new_sandbox/'
/
开头,因此假定它是相对于根目录的。删除前导的
/

这样做,不要太多额外的斜杠

root="/home"
os.path.join(root,"build","test","sandboxes",todaystr,"new_sandbox")

os.path.join()

哪怕是一刀都会毁了它

因此,它只有在与某种参考点一起使用时才有意义,例如
os.environ['HOME']
os.path.dirname(\uu文件\uu)

os.path.join()
可与
os.path.sep
结合使用,以创建绝对路径而非相对路径

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

帮助理解这个奇怪的行为为什么不是完全可怕的,考虑一个应用程序,它接受一个配置文件名作为一个参数:

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
或类似文件)


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

要使您的功能更具可移植性,请将其作为一种方式使用:

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


请注意,如果您使用
os.path.join()
包含已包含点的扩展名,则类似的问题可能会困扰您,这是使用
os.path.splitext()时自动发生的情况。在本例中:

components = os.path.splitext(filename)
prefix = components[0]
extension = components[1]
return os.path.join("avatars", instance.username, prefix, extension)
即使
扩展名
可能是
.jpg
,最终也会得到一个名为“foobar”的文件夹,而不是一个名为“foobar.jpg”的文件。要防止出现这种情况,需要单独附加扩展名:

return os.path.join("avatars", instance.username, prefix) + extension

对于具有现有联接的字符串,请尝试组合使用
拆分(“/”
*

import os

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

os.path.join(*home.split("/"), todaystr, *new.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','sandboxs','']

列表前面的
*
将列表中的每一项分解为它自己的参数

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.path.join('/home/build/test/sandboxes/', todaystr, '/new_sandbox/'.strip('/'))
'/home/build/test/sandboxes/04122019/new_sandbox'

我建议从第二个字符串和以下字符串中删除字符串
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)

-1:任何字符串都不应包含“/”。os.path.join的一个要点是防止在路径中添加任何斜杠。当然,str.join()的问题在于它不会消除双斜杠。我认为这是使用os.path.join的人们的主要目的。e、 g.“/”.join(['/etc/','/conf'])会导致三个斜杠:“/etc///conf'@DustinRasener您可以用来实现这个目标。不知道人们为什么对os.path.join行为感到沮丧。在其他语言中,等效路径联接库/方法的行为完全相同。它更安全,更有意义。这是令人沮丧的,因为这是一种隐性魔法,与“显性优于隐性”的说法相反。事实确实如此。语言设计者可能认为他们知道得更好,但偶尔想这样做显然有安全的理由。现在我们不能。这就是为什么我们不能有好东西。使用
os.path.sep
作为构建绝对路径的第一个元素比这里的任何其他答案都好!使用
os.path
而不是基本str方法的全部目的是避免编写
/
。将每个子目录作为新参数并删除所有斜杠也很好。最好通过检查确保
todaystr
不以斜杠开头!;)这也适用于windows(python 2.7.6)。它没有引用“C:\”并加入子目录。谢谢!在读到你的答案之前,我一直讨厌这种行为!这是在中记录的,但不是它的动机。此时此刻,当你需要许多人认为糟糕的解决方案时。不得不不同意,这是完全糟糕的。在这种情况下,您不应该使用幼稚的
sys.argv
输入来确定是否在
config_root
前加前缀。所有
os.path.join
都应该关注的是连接文件路径元素。问题是名称选择不当。
os.path.join(p1,p2)
所做的并不是真正地连接
p1
p2
,而是采取
p2
相对于
p1
(或者如果
p2
是绝对路径)的方式,如果os.sep实际上是
“\”
?然后您的第一个示例变成
os.path.join