如何在Python中获取父目录?

Mri*_*lla 306 python

有人能告诉我如何以跨平台的方式在Python中获取路径的父目录.例如

C:\Program Files ---> C:\
Run Code Online (Sandbox Code Playgroud)

C:\ ---> C:\
Run Code Online (Sandbox Code Playgroud)

如果目录没有父目录,则返回目录本身.问题可能看似简单,但我无法通过谷歌进行挖掘.

ken*_*der 412

试试这个:

from pathlib import Path
path = Path("/here/your/path/file.txt")
print(path.parent)
Run Code Online (Sandbox Code Playgroud)

pathlib您想要父母的路径在哪里.

  • 你的答案是正确的但是错综复杂; `os.path.dirname`就是这个函数,就像`a + = 5-4`比'a + = 1`更复杂.该问题仅请求父目录,而不是是否存在或假设符号链接妨碍*true*父目录. (126认同)
  • @tzot:不幸的是`os.path.dirname`给出了不同的结果,具体取决于路径中是否包含尾部斜杠.如果你想要可靠的结果,你需要在上面的答案中使用`os.path.join`方法. (42认同)
  • 由于这显然足够复杂以保证StackOverflow问题,我觉得这应该作为内置函数添加到os.path库中. (19认同)
  • 它是`os.pardir`,而不是`os.path.pardir`. (15认同)
  • @bouteillebleu:`os.pardir`和`os.path.pardir`实际上都是正确的(它们是相同的). (8认同)
  • @Artfunkel谢谢.为了完整性,你的评论应该附在答案中. (3认同)
  • 我尝试将代码片段更改为 `os.pardir`,但不幸的是 Stack Overflow“编辑必须至少有 6 个非空格字符”。它似乎足够聪明,可以检测空白填充;也许有一天OP可以纠正这个问题...... (2认同)

Wai*_*ung 306

使用os.path.dirname:

>>> os.path.dirname(r'C:\Program Files')
'C:\\'
>>> os.path.dirname('C:\\')
'C:\\'
>>>
Run Code Online (Sandbox Code Playgroud)

警告:os.path.dirname()根据路径中是否包含尾部斜杠,给出不同的结果.这可能是也可能不是您想要的语义.参看 @kender的答案使用os.path.join(yourpath, os.pardir).

  • 原始海报没有说明目录必须存在.有很多路径名方法除了字符串操作之外什么都不做.验证路径名是否实际存在需要磁盘访问权限.取决于应用程序,这可能是也可能不是可取的. (40认同)
  • 此解决方案对尾随os.sep敏感.说os.sep =='/'.dirname(foo/bar) - > foo,但是dirname(foo/bar /) - > foo/bar (9认同)
  • 这是设计的.它归结为具有尾随/的路径的解释.你认为"path1"等于"path1 /"吗?图书馆使用最普遍的解释,它们是截然不同的.在某些情况下,人们可能希望将它们视为等同物.在这种情况下,您可以先执行rstrip('/').如果图书馆选择其他解释,你将失去忠诚度. (6认同)
  • `os.path.dirname(r'C:\ Program Files')`什么?Python只是为您提供文件'Program Files'所在的目录.更重要的是,它甚至不必存在,注意:`os.path.dirname(r'c:\ i\like\to\eat\pie')`输出`'c:\\ i \\ like\\到\\ eat'` (5认同)
  • @Ryan,我不知道.编写了一整套RFC 1808来解决URI中相对路径的问题以及存在和不存在尾随/的所有细微之处.如果您知道任何文档说它们应该被视为等效,请指出. (3认同)
  • @WaiYipTung嗯,好吧,看起来很傻,但我认为这只是图书馆的决定.那么更有意义. (2认同)

wp-*_*com 104

在Python 3.4+中

from pathlib import Path
Path('C:\Program Files').parent
Run Code Online (Sandbox Code Playgroud)

Python文档


附加信息

新的pathlib库汇集并简化了使用路径和常见文件操作.以下是文档中的一些示例.

在目录树中导航:

>>>
>>> p = Path('/etc')
>>> q = p / 'init.d' / 'reboot'
>>> q
PosixPath('/etc/init.d/reboot')
>>> q.resolve()
PosixPath('/etc/rc.d/init.d/halt')
Run Code Online (Sandbox Code Playgroud)

查询路径属性:

>>>
>>> q.exists()
True
>>> q.is_dir()
False
Run Code Online (Sandbox Code Playgroud)

  • 此解决方案对尾随`os.sep` 不敏感! (5认同)
  • 这是唯一合理的答案.如果您被迫使用Python 2,只需`pip install pathlib2`并使用backport. (4认同)

ivo*_*ivo 32

import os
p = os.path.abspath('..')
Run Code Online (Sandbox Code Playgroud)

C:\Program Files ---> C:\\\

C:\ ---> C:\\\

  • 这只是获取CWD的父节点,而不是OP询问的任意路径的父节点. (7认同)

ben*_*bin 25

@kender的另一种解决方案

import os
os.path.dirname(os.path.normpath(yourpath))
Run Code Online (Sandbox Code Playgroud)

yourpath您想要父母的路径在哪里.

但是这个解决方案并不完美,因为它不会处理yourpath空字符串或点的情况.

这个其他解决方案将更好地处理这个角落的情况:

import os
os.path.normpath(os.path.join(yourpath, os.pardir))
Run Code Online (Sandbox Code Playgroud)

这里可以找到的每种情况的输出(输入路径是相对的):

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))    => '../..'
Run Code Online (Sandbox Code Playgroud)

输入路径是绝对的(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))     => '/'
Run Code Online (Sandbox Code Playgroud)


Dan*_*nes 18

os.path.split(os.path.abspath(mydir))[0]
Run Code Online (Sandbox Code Playgroud)

  • @AnthonyBriggs,我刚刚在Ubuntu 12.04上使用Python 2.7.3尝试了这个,它似乎工作正常.`os.path.split(os.path.abspath("this/is/a/dir /"))[0]`按预期返回`'/ home/daniel/this/is/a'`.我现在还没有运行Windows框来检查那里.您在什么设置上观察到您报告的行为? (2认同)

Ign*_*ams 13

os.path.abspath(os.path.join(somepath, '..'))
Run Code Online (Sandbox Code Playgroud)

注意:

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', '..'))
Run Code Online (Sandbox Code Playgroud)


小智 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 "------------------------------------------------------------"
Run Code Online (Sandbox Code Playgroud)


Sou*_*dra 7

>>> import os
>>> os.path.basename(os.path.dirname(<your_path>))
Run Code Online (Sandbox Code Playgroud)

例如在 Ubuntu 中:

>>> my_path = '/home/user/documents'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'user'
Run Code Online (Sandbox Code Playgroud)

例如在 Windows 中:

>>> my_path = 'C:\WINDOWS\system32'
>>> os.path.basename(os.path.dirname(my_path))
# Output: 'WINDOWS'
Run Code Online (Sandbox Code Playgroud)

这两个例子都在 Python 2.7 中尝试过


8bi*_*kie 6

如果你想名称是作为参数,并提供该文件的直接父文件夹的不是绝对路径到该文件中:

os.path.split(os.path.dirname(currentDir))[1]

即具有的currentDir/home/user/path/to/myfile/file.ext

上面的命令将返回:

myfile

  • os.path.basename(os.path.dirname(current_dir))也可以在这里使用。 (2认同)

Rak*_*ari 6

假设我们有这样的目录结构

1]

/home/User/P/Q/R
Run Code Online (Sandbox Code Playgroud)

我们想从目录 R 访问“P”的路径,然后我们可以使用

ROOT = os.path.abspath(os.path.join("..", os.pardir));
Run Code Online (Sandbox Code Playgroud)

2]

/home/User/P/Q/R
Run Code Online (Sandbox Code Playgroud)

我们想从目录 R 访问“Q”目录的路径,然后我们可以使用

ROOT = os.path.abspath(os.path.join(".", os.pardir));
Run Code Online (Sandbox Code Playgroud)