【问题标题】:Get absolute paths of all files in a directory获取目录中所有文件的绝对路径
【发布时间】:2012-04-06 16:36:09
【问题描述】:

如何获取 Python 中可能包含多个子文件夹的目录中所有文件的绝对路径?

我知道os.walk() 递归地给了我一个目录和文件的列表,但这似乎并没有让我得到我想要的。

【问题讨论】:

  • 你能举例说明你期望的输入和输出吗

标签: python absolute-path


【解决方案1】:

os.path.abspath 确保路径是绝对的。使用以下辅助函数:

import os

def absoluteFilePaths(directory):
    for dirpath,_,filenames in os.walk(directory):
        for f in filenames:
            yield os.path.abspath(os.path.join(dirpath, f))

【讨论】:

  • 我认为在 os.walk 行上只做一次 abspath 比在循环内做 N 次更好
  • 这行得通,但仅限于“意外”。阅读os.path.join 的合同,如果其中一个论点是,我找不到任何地方可以保证结果是绝对的,尽管这是一个明智的假设。
  • @phihag 这很可靠。这不是“意外”,而且语言也没有那么正式,以至于在文档中没有任何“合同”的概念。据记载,如果一个组件是绝对路径,之前的所有组件都被丢弃,从绝对路径组件继续加入。 Python在这里不能无形地转换成相对路径,也无法修改没有巨大的向后破坏性变化的行为。如果还不服气,你甚至可以直接阅读os.path.join的源码,简洁明了。
【解决方案2】:

所有文件和文件夹:

x = [os.path.abspath(os.path.join(directory, p)) for p in os.listdir(directory)]

图片(.jpg | .png):

x = [os.path.abspath(os.path.join(directory, p)) for p in os.listdir(directory) if p.endswith(('jpg', 'png'))]

【讨论】:

  • 你如何确保这个oneliner中只有文件而不是目录?
【解决方案3】:

从 python 3.5 开始,惯用的解决方案是:

import os

def absolute_file_paths(directory):
    path = os.path.abspath(directory)
    return [entry.path for entry in os.scandir(path) if entry.is_file()]

这不仅读起来更好,而且在许多情况下也更快。 有关更多详细信息(例如忽略符号链接),请参阅原始 python 文档: https://docs.python.org/3/library/os.html#os.scandir

【讨论】:

  • scandir() 不是递归的
【解决方案4】:

试试:

from pathlib import Path
path = 'Desktop'
files = filter(lambda filepath: filepath.is_file(), Path(path).glob('*'))
for file in files:
   print(file.absolute())

【讨论】:

  • 您的导入语句直接导入Path,但随后您在代码中调用pathlib.Path()。目前不运行,除非你修复它。否则很好干净的解决方案@Pygirl。
  • 在这个例子中,不需要从这些文件中生成list,过滤器返回一个生成器。
  • @MaLiN2223:是的,这是真的,但我想存储文件列表,因为当发电机耗尽时,文件将不提供任何信息。无论如何,我已经更新了我的答案:)
【解决方案5】:

如果给os.walk 的参数是绝对的,那么在迭代期间产生的根目录名称也将是绝对的。因此,您只需要使用文件名加入它们:

import os

for root, dirs, files in os.walk(os.path.abspath("../path/to/dir/")):
    for file in files:
        print(os.path.join(root, file))

【讨论】:

  • 好的,我明白你的意思,只是我不想要这些文件,但想要特定的子目录。我已经在下面发布了解决方案。
【解决方案6】:
for root, directories, filenames in os.walk(directory):
 for directory in directories:
         print os.path.join(root, directory)
 for filename in filenames:
     if filename.endswith(".JPG"):
        print filename
        print os.path.join(root,filename)

【讨论】:

  • 虽然这可能会回答作者的问题,但它缺少一些解释性文字和文档链接。如果没有围绕它的一些短语,原始代码 sn-ps 并不是很有帮助。您可能还会发现how to write a good answer 非常有帮助。请编辑您的答案。
【解决方案7】:
from glob import glob


def absolute_file_paths(directory):
    return glob(join(directory, "**"))

【讨论】:

  • 虽然此代码可能会回答问题,但您仍然可以考虑添加一些解释性句子,因为这会增加您的答案对其他用户的价值。
  • 这仅在您还从 os 模块导入 join 时才有效,例如:from os.path import join。不递归处理文件夹。
【解决方案8】:

如果您有 Python 3.4 或更高版本,您可以使用 pathlib(如果您有旧 Python 版本,则可以使用第三方向后移植):

import pathlib
for filepath in pathlib.Path(directory).glob('**/*'):
    print(filepath.absolute())

【讨论】:

  • 这很好,它使用python 3,但它也显示目录。
【解决方案9】:

我想保留子目录的详细信息而不是文件,并且只想要包含一个 xml 文件的子目录。我可以这样做:

for rootDirectory, subDirectories, files in os.walk(eventDirectory):
  for subDirectory in subDirectories:
    absSubDir = os.path.join(rootDirectory, subDirectory)
    if len(glob.glob(os.path.join(absSubDir, "*.xml"))) == 1:
      print "Parsing information in " + absSubDir

【讨论】:

    【解决方案10】:

    可以使用os.path.abspath()将相对路径转为绝对路径:

    file_paths = []
    
    for folder, subs, files in os.walk(rootdir):
      for filename in files:
        file_paths.append(os.path.abspath(os.path.join(folder, filename)))
    

    【讨论】:

    • 当你想加入folder时,这不是加入cwdfilename吗?!
    【解决方案11】:

    试试:

    import os
    
    for root, dirs, files in os.walk('.'):
        for file in files:
            p=os.path.join(root,file)
            print p
            print os.path.abspath(p)
            print
    

    【讨论】:

    • 无论如何要在不捕获隐藏文件的情况下执行此操作?
    • @MarcelMarino if not file.startswith('.')
    猜你喜欢
    • 2023-04-05
    • 1970-01-01
    • 2020-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-12
    • 2012-10-04
    • 2018-12-27
    相关资源
    最近更新 更多