自学内容网 自学内容网

Python--递归与非递归遍历文件夹的方法

递归概念

递归是一种编程技术,允许函数调用自身来解决问题。设计递归函数时,需要考虑基本情况和递归步骤。

递归函数设计

  • 基本情况:递归结束的条件。
  • 递归步骤:函数调用自身解决更小的子问题。

递归方法实现

import os

def get_files_recursion_from_dir(path):
    file_list = []
    if os.path.exists(path):
        for f in os.listdir(path):
            new_path = os.path.join(path, f)
            if os.path.isdir(new_path):
                file_list += get_files_recursion_from_dir(new_path)
            else:
                file_list.append(new_path)
    return file_list

非递归遍历方法

除了递归,以下是几种常用的遍历文件夹的方法:

1. 使用 os.walk()

os.walk() 是一个生成器函数,遍历指定目录及其子目录,生成三元组 (dirpath, dirnames, filenames)

import os

def get_files_walk(path):
    file_list = []
    for dirpath, dirnames, filenames in os.walk(path):
        for filename in filenames:
            file_list.append(os.path.join(dirpath, filename))
    return file_list
2. 使用 glob.glob()glob.iglob()

glob 模块提供通配符搜索文件路径的功能。

import glob

def get_files_glob(path):
    file_list = []
    for filename in glob.iglob(path + "/**/*", recursive=True):
        file_list.append(filename)
    return file_list
3. 使用 pathlib.Path

pathlib 提供面向对象的文件系统路径操作。

from pathlib import Path

def get_files_pathlib(path):
    file_list = [str(file) for file in Path(path).rglob('*')]
    return file_list
4. 使用 scandir()scandir_iter()

scandir() 是一个迭代器,可以遍历目录中的文件和目录。

import os

def get_files_scandir(path):
    file_list = []
    for entry in os.scandir(path):
        if entry.is_file():
            file_list.append(entry.path)
        elif entry.is_dir():
            file_list.extend(get_files_scandir(entry.path))
    return file_list
5. 使用 subprocess

通过调用系统命令,可以使用 subprocess 模块获取文件列表。

import subprocess

def get_files_subprocess(path):
    result = subprocess.run(['find', path, '-type', 'f'], stdout=subprocess.PIPE)
    file_list = result.stdout.decode().split('\n')
    return [file for file in file_list if file]

注意事项

  • 递归函数需要有明确的退出条件,避免栈溢出错误。
  • 递归深度可能受到限制,对于极深的文件夹结构,递归可能不是最佳选择。
  • os.walk() 在遍历过程中遇到权限错误会抛出 OSError
  • 遍历过程中,如果目录结构发生变化,os.walk() 的行为是未定义的。

使用 os.access() 检查文件或目录的权限

os.access() 函数用于检查当前进程是否有权限访问指定的文件或目录。它接受以下模式作为访问权限的检查:

  • os.F_OK:检查文件或目录是否存在。
  • os.R_OK:检查文件是否可读。
  • os.W_OK:检查文件是否可写。
  • os.X_OK:检查文件是否可执行(在UNIX系统上有效)。

使用 os.access() 检查文件或目录的权限:

  1. 检查文件或目录是否存在
import os

path = '/path/to/file/or/directory'
if os.access(path, os.F_OK):
    print(f"{path} 存在。")
else:
    print(f"{path} 不存在。")
  1. 检查文件是否可读
if os.access(path, os.R_OK):
    print(f"{path} 是可读的。")
else:
    print(f"{path} 不可读。")
  1. 检查文件是否可写
if os.access(path, os.W_OK):
    print(f"{path} 是可写的。")
else:
    print(f"{path} 不可写。")
  1. 检查文件是否可执行(仅UNIX系统):
if os.access(path, os.X_OK):
    print(f"{path} 是可执行的。")
else:
    print(f"{path} 不可执行。")
  1. 组合检查
if os.access(path, os.R_OK | os.W_OK):
    print(f"{path} 是可读写的。")

避免 os.walk() 遍历时的权限错误

在使用 os.walk() 遍历文件夹时,可能会遇到权限错误。以下是一些避免或处理权限错误的策略:

  1. 检查权限:在尝试访问目录之前,使用 os.access() 函数检查当前用户是否有权限读取该目录。

  2. 捕获异常:在遍历过程中,使用 try-except 块来捕获可能发生的 OSErrorPermissionError 异常,并决定如何处理这些异常(例如,跳过该目录或记录错误信息)。

  3. 使用更宽松的权限:如果程序运行在具有较少权限的用户下,考虑以更高权限运行程序,例如使用 sudo(在Linux系统中)。

  4. 修改文件夹权限:在某些情况下,可能需要修改文件夹的权限,以便用户可以访问。这可以通过 os.chmod() 函数实现,但需要谨慎使用,以避免安全风险。

  5. 记录错误:在无法访问的目录上记录错误信息,可能对调试或了解程序运行情况有帮助。

  6. 用户反馈:如果程序是交互式的,可以向用户报告权限错误,并提示他们采取适当的行动。

  7. 使用日志:记录权限错误的详细信息到日志文件中,有助于事后分析。

  8. 递归检查:在递归调用 os.walk() 之前,先检查子目录的权限,如果无权限则不进行递归。

  9. 使用 pathlib:虽然 pathlibPath.rglob() 方法在遇到权限错误时也会抛出异常,但它提供了更现代的面向对象的API,可以与异常处理结合使用。

选择哪种方法取决于具体需求和个人偏好。递归是一种强大的技术,但需要谨慎使用。非递归方法如 os.walk()pathlib.Path.rglob() 提供了易于理解和使用的替代方案。


原文地址:https://blog.csdn.net/mmd666/article/details/140596731

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!