You need to enable JavaScript to run this app. Python中shutil.copy报Errno13权限拒绝但shutil.move运行正常问题解析
优惠活动
大模型
产品
解决方案
定价
更多

Python中shutil.copy报Errno13权限拒绝但shutil.move运行正常问题解析

报错根源解析
  • 你遇到的PermissionError 并非系统层面的目录访问权限不足,核心原因是shutil模块下两个函数的设计适用场景存在本质差异,无法直接互换参数使用。
  • shutil.move() 支持传入文件、文件夹两类路径作为源对象:函数内部会先判断源路径的类型,如果是文件夹就走专门的目录迁移逻辑,不会尝试把目录本身当二进制文件读取,因此传入C:\Documents\Input这类目录路径可以正常运行。
  • shutil.copy() 仅支持传入单个文件作为源对象,不具备目录递归遍历能力:从错误堆栈可以看到,传入目录路径后函数直接进入了copyfile()的处理分支,该分支会执行open(src, 'rb')逻辑——尝试把C:\Documents\Input这个文件夹本身按二进制文件打开。Windows系统本身禁止将目录路径作为普通文件打开,因此直接抛出权限拒绝错误。
  • 哪怕给Python授予最高级别的管理员权限,这种把目录当文件打开的操作依然会报同样的错误,和系统权限配置无关。
适配需求的解决方案

你的需求是“把Input目录下的所有文件、文件夹结构完整复制到Output,同时保留源路径内容”,可以根据场景选择以下实现方式:

  • 方案1:使用Python内置的目录递归复制工具shutil.copytree(),和shutil.move()的目录处理逻辑对齐,是最简洁的实现。
    需要注意shutil.copytree()在Python3.8及以上版本支持dirs_exist_ok参数,允许目标Output目录提前存在,不会触发FileExistsError。参考代码:
    import shutil
    
    input_path = r'C:\Documents\Input'
    output_path = r'C:\Documents\Output'
    
    shutil.copytree(
        src=input_path,
        dst=output_path,
        dirs_exist_ok=True
    )
    

    路径结构注意:shutil.copytree() 和 shutil.move() 的路径拼接逻辑存在差异,避免预期错位:

    • 若你之前运行shutil.move(input_path, output_path)时,因为output_path是已存在的目录,最终文件会被移动到C:\Documents\Output\Input\ 路径下(也就是把Input整个文件夹作为子项放到Output目录里)。
    • 如果用上述copytree代码,会把Input目录内部的所有内容直接复制到Output根目录下,不会生成嵌套的Input子文件夹。
      如果你的预期是和move生成的目录结构完全一致,只需要把copytree的dst参数修改为os.path.join(output_path, "Input") 即可。
  • 方案2:如果需要对复制过程加自定义逻辑(比如跳过特定类型文件、过滤临时目录),可以手动遍历源目录结构,逐个完成目录创建、文件复制。参考实现:
    import os
    import shutil
    
    input_path = r'C:\Documents\Input'
    output_path = r'C:\Documents\Output'
    
    for root, _, files in os.walk(input_path):
        # 计算源路径下的相对层级,保证复制后的目录结构和源目录完全一致
        relative_level = os.path.relpath(root, input_path)
        current_target_dir = os.path.join(output_path, relative_level)
        os.makedirs(current_target_dir, exist_ok=True)
    
        # 逐文件复制,copy2会保留文件的修改时间、权限等元数据,和move的迁移效果一致
        for file_name in files:
            source_file = os.path.join(root, file_name)
            target_file = os.path.join(current_target_dir, file_name)
            shutil.copy2(source_file, target_file)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.11.06 22:24:02