有人能告诉我如何以跨平台的方式在 Python 中获取路径的父目录吗?例如:
C:\Program Files ---> C:\
和
C:\ ---> C:\
如果目录没有父级目录,则返回该目录本身。这个问题看起来很简单,但我通过谷歌也找不到答案。
有人能告诉我如何以跨平台的方式在 Python 中获取路径的父目录吗?例如:
C:\Program Files ---> C:\
和
C:\ ---> C:\
如果目录没有父级目录,则返回该目录本身。这个问题看起来很简单,但我通过谷歌也找不到答案。
使用 pathlib
模块。
from pathlib import Path
path = Path("/here/your/path/file.txt")
print(path.parent.absolute())
试试这个:
import os
print os.path.abspath(os.path.join(yourpath, os.pardir))
其中yourpath
是您要获取其父级路径的路径。
os.path.dirname
是此功能的函数,就像 a+=5-4
比 a+=1
更加复杂一样。问题仅要求父目录,而不涉及其是否存在或假设符号链接妨碍了真正的父目录。 - tzotos.pardir
,但不幸的是 Stack Overflow 提示“编辑必须至少包含 6 个非空格字符”。它似乎足够聪明,可以检测到空格填充;也许 OP 以后可以纠正这个问题... - monsuros.path.dirname
会给出不同的结果。如果你想得到可靠的结果,就需要使用上面答案中提到的os.path.join
方法。 - Artfunkel使用os.path.dirname
:
>>> os.path.dirname(r'C:\Program Files')
'C:\\'
>>> os.path.dirname('C:\\')
'C:\\'
>>>
注意:根据路径中是否包含结尾斜杠,os.path.dirname()
会返回不同的结果。这可能与您想要的语义相符,也可能不相符。请参考 @kender 的答案,使用 os.path.join(yourpath, os.pardir)
。
os.path.dirname(r'C:\Program Files')
是什么?Python只是给出了文件'Program Files'所在的目录。此外,它甚至不必存在,看这个例子:os.path.dirname(r'c:\i\like\to\eat\pie')
的输出结果是 'c:\\i\\like\\to\\eat'
。 - Nick Tfrom pathlib import Path
Path('C:\Program Files').parent
# Returns a Pathlib object
import os.path
os.path.dirname('C:\Program Files')
# Returns a string
如果以下情况符合,请使用传统方法:
您担心现有代码在使用Pathlib对象时会生成错误。(因为Pathlib对象无法与字符串连接。)
您的Python版本低于3.4。
您需要一个字符串,并且已经得到了一个字符串。例如,如果您有一个表示文件路径的字符串,并且您想获取其父目录以便将其放入JSON字符串中。对于这个问题,将其转换为Pathlib对象再转换回来可能有些愚蠢。
如果以上情况都不适用,则使用Pathlib。
如果您不知道Pathlib是什么,那么Pathlib模块是一个非常好的模块,可以让您更轻松地处理文件。大多数如果不是所有内置的Python模块都可以接受Pathlib对象和字符串。下面我从Pathlib文档中摘选了一些示例,展示了一些Pathlib的妙处。
浏览目录树:
>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> <a rel="noreferrer" href="https://docs.python.org/3/library/pathlib.html#pathlib.Path.resolve">q.resolve()</a>
PosixPath('/etc/rc.d/init.d/halt')
查询路径属性:
>>> <a rel="noreferrer" href="https://docs.python.org/3/library/pathlib.html#pathlib.Path.exists">q.exists()</a>
True
>>> <a rel="noreferrer" href="https://docs.python.org/3/library/pathlib.html#pathlib.Path.is_dir">q.is_dir()</a>
False
pip install pathlib2
并使用后移版本即可。 - Navinos.sep
的影响! - Dylan Fpath_as_string = str(Path(<somepath>))
。 - Johnimport os
p = os.path.abspath('..')
C:\Program Files
---> C:\\\
C:\
---> C:\\\
os.path.abspath(r'E:\O3M_Tests_Embedded\branches\sw_test_level_gp\test_scripts\..\..')
结果为:
E:\\O3M_Tests_Embedded\\branches
- Arindam Roychowdhury/
。 - loretoparisi@kender提供的另一种解决方案。
import os
os.path.dirname(os.path.normpath(yourpath))
其中yourpath
是您想要获取父级的路径。
但是,该解决方案并不完美,因为它无法处理yourpath
为空字符串或点的情况。
另一种解决方案将更好地处理这种特殊情况:
import os
os.path.normpath(os.path.join(yourpath, os.pardir))
以下是能够找到的每种情况的输出(输入路径为相对路径):
os.path.dirname(os.path.normpath('a/b/')) => 'a'
os.path.normpath(os.path.join('a/b/', os.pardir)) => 'a'
os.path.dirname(os.path.normpath('a/b')) => 'a'
os.path.normpath(os.path.join('a/b', os.pardir)) => 'a'
os.path.dirname(os.path.normpath('a/')) => ''
os.path.normpath(os.path.join('a/', os.pardir)) => '.'
os.path.dirname(os.path.normpath('a')) => ''
os.path.normpath(os.path.join('a', os.pardir)) => '.'
os.path.dirname(os.path.normpath('.')) => ''
os.path.normpath(os.path.join('.', os.pardir)) => '..'
os.path.dirname(os.path.normpath('')) => ''
os.path.normpath(os.path.join('', os.pardir)) => '..'
os.path.dirname(os.path.normpath('..')) => ''
os.path.normpath(os.path.join('..', os.pardir)) => '../..'
输入路径是绝对路径(Linux路径):
os.path.dirname(os.path.normpath('/a/b')) => '/a'
os.path.normpath(os.path.join('/a/b', os.pardir)) => '/a'
os.path.dirname(os.path.normpath('/a')) => '/'
os.path.normpath(os.path.join('/a', os.pardir)) => '/'
os.path.dirname(os.path.normpath('/')) => '/'
os.path.normpath(os.path.join('/', os.pardir)) => '/'
os.path.split(os.path.abspath(mydir))[0]
os.path.split(os.path.abspath("this/is/a/dir/"))[0]
返回预期的 '/home/daniel/this/is/a'
。我目前没有可用的Windows机器来检查。您在何种设置中观察到您所报告的行为? - Dan Menesparentdir = os.path.split(os.path.apspath(dir[:-1]))[0]
。我确信这个方法是可行的,因为如果路径末尾有斜杠,则会被删除;如果没有斜杠,这个方法仍然有效(即使路径的最后一部分只有一个字符),因为前面有斜杠。当然,这假设路径是正确的,而不是像/a//b/c///d////
这样的路径(在Unix中仍然是有效的),但大多数情况下它们是正确的,特别是当你使用os.path.abspath
或任何其他os.path
函数时。 - dylnmcos.path.split("a/b//c/d///")
这样的东西,那么它是不起作用的,例如cd //////dev//////
等同于cd /dev/
或cd /dev
;所有这些在Linux中都是有效的。我刚想出了这个方法,可能会有用:os.path.split(path[:tuple(ind for ind, char in enumerate(path) if char != "/" and char != "\\")[-1]])[0]
。(这本质上是搜索最后一个非斜杠,并获取路径子字符串直到该字符。)我使用了path = "/a//b///c///d////"
,然后运行了上述语句,得到了'/a//b///c'
。 - dylnmcos.path.abspath(os.path.join(somepath, '..'))
请注意:
import posixpath
import ntpath
print ntpath.abspath(ntpath.join('C:\\', '..'))
print ntpath.abspath(ntpath.join('C:\\foo', '..'))
print posixpath.abspath(posixpath.join('/', '..'))
print posixpath.abspath(posixpath.join('/home', '..'))
>>> import os
>>> os.path.basename(os.path.dirname(<your_path>))
>>> my_path = '/home/user/documents'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'user'
>>> my_path = 'C:\WINDOWS\system32'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'WINDOWS'
以下两个例子均在 Python 2.7 中尝试
import os
print"------------------------------------------------------------"
SITE_ROOT = os.path.dirname(os.path.realpath(__file__))
print("example 1: "+SITE_ROOT)
PARENT_ROOT=os.path.abspath(os.path.join(SITE_ROOT, os.pardir))
print("example 2: "+PARENT_ROOT)
GRANDPAPA_ROOT=os.path.abspath(os.path.join(PARENT_ROOT, os.pardir))
print("example 3: "+GRANDPAPA_ROOT)
print "------------------------------------------------------------"
1]
/home/User/P/Q/R
ROOT = os.path.abspath(os.path.join("..", os.pardir));
2]
/home/User/P/Q/R
ROOT = os.path.abspath(os.path.join(".", os.pardir));