You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Python中列出文件或目录目标的所有文件与文件夹?

函数说明

我想要编写一个函数,接收文件系统中的路径目标target作为输入,它可以是目录,也可以是文件。
该函数需要返回target下所有子目标的文件和文件夹列表。

详细说明如下:

  • 若target是文件,返回值为包含该文件完全限定路径的长度为1的列表。
  • 若target是目录,返回值应包含该目录的递归子内容,包括目录本身。
  • 返回项需按排序后的顺序排列
  • 返回项需能区分是文件路径还是目录路径
Stack Overflow上的已有问题

Stack Overflow上有类似问题,但均未覆盖此场景。
以下是简要总结:

  • 如何列出目录的所有文件?
  • 获取当前目录的所有子目录列表

这两个问题的答案均假设目标是目录,无法处理目标为文件的情况。此外,第一个问题仅返回文件,不包含目录;第二个问题仅返回目录,不包含文件。

实现策略

该函数应拆分为三个步骤:

  1. 第一步:获取相对路径
  2. 第二步:通过映射操作将相对路径转换为绝对(完全限定)路径
  3. 第三步:对返回项进行排序

这种设计具备高度灵活性,每个函数仅负责一项任务且可组合,属于优秀的软件设计,即所谓的简洁设计。

另一种更优的设计可能是将文件和目录的收集拆分为两个独立函数,但这会导致目标被遍历两次,降低性能。

基础函数选择

我了解到有几种基础函数可选:

  • os.listdir
  • os.scandir
  • os.walk
  • os.fwalk
  • 或许还有其他?

我不确定哪种是最佳选择。

尝试的解决方案

我已开始尝试实现,但因输入的目标路径可能是文件或目录,初始状态未知,实现起来相当复杂。这意味着接口层的逻辑需要与递归调用的逻辑不同。

我未能找到简单优雅的解决方案,因此认为肯定存在更合适的方法,只是我尚未发现。

基于以下示例:

import os

def fast_scandir(target_dir: str) -> list[str]:
    items = []
    for f in os.scandir(target_dir):
        if f.is_dir():
            items.extend(fast_scandir(f.path))
        if f.is_file():
            items.append(f.path)
    items.sort()
    return items

该示例是一个简单的解决方案,但未满足所有需求,我据此写出了以下代码:

# 接口层,接收`target`,未知其为文件或目录
def fast_scandir_3(target:str) -> list[tuple[str, str]]:
    items:list[tuple[str, str]] = []
    if os.path.isfile(target):
        item = ('f', target)
        items.extend(_fast_scandir_3_impl(item))
    elif os.path.isdir(target):
        item = ('d', target)
        items.extend(_fast_scandir_3_impl(item))
    return items

以下(实现层)代码非常糟糕,过于复杂,难以阅读和理解,肯定存在更直接的实现方式:

# 实现层
# TODO:后续将添加`sorted`排序和完全限定路径支持
def _fast_scandir_3_impl(target:tuple[str, str]) -> list[tuple[str, str]]:
    items:list[tuple[str, str]] = []
    items.append(target)
    if target[0] == 'f':
        pass
    elif target[0] == 'd':
        target_path = target[1]
        for subtarget in os.listdir(target_path):
            if os.path.isfile(subtarget):
                target = ('f', subtarget)
                items.extend(_fast_scandir_3_impl(target))
            elif os.path.isdir(subtarget):
                target = ('d', subtarget):
                items.extend(_fast_scandir_3_impl(target ))
    return items

实现完全限定路径的思路:

def _fast_scandir_3_fully_qualified_impl(target:tuple[str, str]) -> list[tuple[str, str]]:
    return (
        list(
            map(
                lambda item: (item[0], os.path.abspath(item[1])),
                _fast_scandir_3_impl(target),
            )
        )
    )

实现排序的思路:

def _fast_scandir_3_fully_qualified_sorted_impl(target:tuple[str, str]) -> list[tuple[str, str]]:
    return sorted(_fast_scandir_3_fully_qualified_impl(target), key=lambda pair: pair[1])

最严重的问题是该实现并未完成预期功能。

此外,还有一些疑问:

  • 使用listdir实现是否正确?
  • 使用sorted对返回项排序是否是最高效的方式?(上述实现中未展示)

内容的提问来源于stack exchange,提问作者user2138149

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:05:21