很多刚学 Python 的朋友,在做自动化办公、批量整理文件、备份数据时,都会遇到一个非常基础但又很高频的需求:
把一个文件复制到另一个位置。
这时候,Python 标准库里的 shutil.copy() 就非常好用。它简单直接,上手快,非常适合初学者。
这篇文章就用最通俗的方式,带你彻底搞懂:
-
shutil.copy()是什么 -
shutil.copy()怎么用 -
复制文件时会不会覆盖
-
和
copy2()、copyfile()有什么区别 -
实战中常见报错怎么解决
一、什么是 shutil.copy?
shutil 是 Python 自带的一个高级文件操作模块,专门用来处理复制、移动、删除、打包等文件系统任务。
其中:
shutil.copy(src, dst)
表示:
-
src:源文件路径 -
dst:目标路径
它的作用就是:
把 src 文件复制到 dst 指定的位置。

二、最基础的用法
先来看一个最简单的例子。
import shutil
shutil.copy("a.txt", "b.txt")
这段代码的意思是:
把当前目录下的 a.txt 复制一份,并命名为 b.txt。
如果 b.txt 不存在,就会新建。
如果 b.txt 已经存在,通常会被直接覆盖。
三、复制到指定文件夹怎么写?
很多时候,我们不是想改名,而是想复制到某个目录里。
例如:
import shutil
shutil.copy("a.txt", "D:/test/")
这段代码表示把 a.txt 复制到 D:/test/ 文件夹中。
复制后,目标文件通常会变成:
D:/test/a.txt
也就是说:
-
如果
dst是一个文件夹,Python 会保留原文件名 -
如果
dst是一个完整文件名,Python 会复制并改名
四、复制并重命名文件
比如你想把 a.txt 复制到另一个目录,并且顺便改个名字:
import shutil
shutil.copy("a.txt", "D:/test/new_a.txt")
执行后,目标位置会生成一个新的文件:
D:/test/new_a.txt
这在做文件备份、批量生成副本时特别常见。
五、shutil.copy 会复制什么内容?
shutil.copy() 主要会复制:
-
文件内容
-
文件权限信息(部分元数据)
但它不会完整复制所有元数据。
如果你不仅想复制文件内容,还想尽可能保留原文件的修改时间、访问时间等信息,通常更推荐使用:
shutil.copy2()
例如:
import shutil
shutil.copy2("a.txt", "D:/test/")
六、copy、copy2、copyfile 有什么区别?
这是很多初学者最容易混淆的地方。
1)shutil.copyfile()
只复制文件内容,不复制权限、时间等信息。
import shutil
shutil.copyfile("a.txt", "b.txt")
特点:
-
目标必须是完整文件名
-
不能直接写成目录
-
更偏底层一点
2)shutil.copy()
复制文件内容 + 权限信息。
import shutil
shutil.copy("a.txt", "D:/test/")
特点:
-
最常用
-
可以复制到目录
-
适合绝大多数日常开发场景
3)shutil.copy2()
复制文件内容 + 更完整的元数据。
import shutil
shutil.copy2("a.txt", "D:/test/")
特点:
-
比
copy()保留的信息更多 -
更适合备份场景
简单总结
如果你只是想:
“把文件复制过去就行”
那直接用:
shutil.copy()
通常就够了。
七、复制文件时目标文件不存在怎么办?
不用担心。
如果目标路径中的文件名不存在,shutil.copy() 会自动创建目标文件。
例如:
import shutil
shutil.copy("a.txt", "D:/test/backup.txt")
如果 backup.txt 不存在,会直接创建并复制过去。
但要注意:
前提是目标目录 D:/test/ 必须已经存在。
如果目录不存在,就会报错。
八、目标目录不存在会怎样?
例如下面这段代码:
import shutil
shutil.copy("a.txt", "D:/abc/test/")
如果 D:/abc/test/ 这个目录不存在,程序通常会报错,类似:
FileNotFoundError
所以更稳妥的写法是先创建目录,再复制文件。
import os
import shutil
dst_dir = "D:/abc/test/"
os.makedirs(dst_dir, exist_ok=True)
shutil.copy("a.txt", dst_dir)
这里的:
os.makedirs(dst_dir, exist_ok=True)
意思是:
-
如果目录不存在,就自动创建
-
如果已经存在,也不会报错
这是一种非常实用的写法。
九、实战:把一个文件备份到 backup 文件夹
下面写一个更贴近实际项目的小案例。
需求:
-
把
report.xlsx复制到backup文件夹 -
如果文件夹不存在,自动创建
代码如下:
import os
import shutil
src_file = "report.xlsx"
dst_dir = "backup"
os.makedirs(dst_dir, exist_ok=True)
shutil.copy(src_file, dst_dir)
print("文件备份完成")
运行后,当前目录下会生成一个 backup 文件夹,并把 report.xlsx 复制进去。
这个思路在自动化办公里非常常见,比如:
-
备份日报
-
归档合同
-
自动保存日志文件
-
批量整理下载目录
十、实战:批量复制多个文件
如果你有很多文件要一起复制,也可以配合循环来做。
import os
import shutil
file_list = ["a.txt", "b.txt", "c.txt"]
dst_dir = "backup_files"
os.makedirs(dst_dir, exist_ok=True)
for file_name in file_list:
if os.path.exists(file_name):
shutil.copy(file_name, dst_dir)
print(f"{file_name} 复制完成")
else:
print(f"{file_name} 不存在,跳过")
这样就可以把多个文件批量复制到指定目录中。
十一、shutil.copy 会覆盖已有文件吗?
这个问题很多人都会问。
一般来说:
如果目标位置已经有同名文件,shutil.copy() 会直接覆盖。
例如:
import shutil
shutil.copy("a.txt", "D:/test/a.txt")
如果 D:/test/a.txt 已经存在,那么原来的文件内容很可能会被新文件覆盖掉。
所以在正式项目里,最好先判断一下。
import os
import shutil
src_file = "a.txt"
dst_file = "D:/test/a.txt"
if not os.path.exists(dst_file):
shutil.copy(src_file, dst_file)
print("复制成功")
else:
print("目标文件已存在,未执行复制")
如果你想避免覆盖,这样写会更安全。
十二、如何复制后自动改名,避免覆盖?
有些场景下,目标文件已经存在,但你又不想覆盖它,可以给新文件自动加时间戳。
例如:
import os
import shutil
from datetime import datetime
src_file = "a.txt"
dst_dir = "backup"
os.makedirs(dst_dir, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
dst_file = os.path.join(dst_dir, f"a_{timestamp}.txt")
shutil.copy(src_file, dst_file)
print("复制成功:", dst_file)
这样每次复制都会得到一个新的文件名,非常适合做备份。
十三、常见报错及解决办法
1)FileNotFoundError
常见原因:
-
源文件不存在
-
目标目录不存在
解决方法:
-
检查
src路径是否正确 -
先用
os.makedirs()创建目标目录
2)PermissionError
常见原因:
-
文件正在被别的程序占用
-
没有写入权限
解决方法:
-
关闭正在占用该文件的软件
-
检查目录权限
-
尝试以管理员身份运行程序
3)源路径写错
Windows 下路径写法经常出问题,比如:
"D:\test\a.txt"
这里的 \t 可能会被当成转义字符。
更推荐这样写:
r"D:\test\a.txt"
或者:
"D:/test/a.txt"
这两种写法都更稳。
十四、推荐用法:配合 pathlib 写得更优雅
如果你用的是较新的 Python 版本,也可以结合 pathlib。
from pathlib import Path
import shutil
src = Path("a.txt")
dst_dir = Path("backup")
dst_dir.mkdir(exist_ok=True)
shutil.copy(src, dst_dir)
这样路径处理会更清晰,代码也更现代一些。
十五、总结:什么时候该用 shutil.copy?
如果你现在的需求是:
-
复制一个文件到另一个地方
-
复制到目录中并保留原名
-
复制后顺便改名
-
做简单的文件备份
那么:
shutil.copy()
就是最实用、最省事的选择。
你只需要记住一句话:
shutil.copy(src, dst),把源文件复制到目标位置,目标可以是文件名,也可以是目录。
如果你还想保留更多文件元数据,就用:
shutil.copy2()
如果你只想复制纯内容,就用:
shutil.copyfile()
十六、完整示例代码
最后附上一段比较实用的完整示例,适合直接练习:
import os
import shutil
from datetime import datetime
src_file = "a.txt"
dst_dir = "backup"
if not os.path.exists(src_file):
print("源文件不存在")
else:
os.makedirs(dst_dir, exist_ok=True)
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
dst_file = os.path.join(dst_dir, f"a_{timestamp}.txt")
shutil.copy(src_file, dst_file)
print("文件复制成功:", dst_file)
这个例子实现了:
-
判断源文件是否存在
-
自动创建目标目录
-
自动生成不重复文件名
-
执行复制操作
非常适合拿来做备份脚本的基础模板。
结尾
shutil.copy() 虽然只是 Python 文件操作中的一个小知识点,但在实际开发、自动化办公、脚本工具中出现的频率非常高。
把这个方法搞明白后,你后面再学:
-
批量文件整理
-
自动备份脚本
-
下载文件归档
-
自动化办公处理
都会轻松很多。
如果你是刚开始学 Python,建议你亲手把文中的几个示例都敲一遍,理解会比单纯看文章快得多。
1217

被折叠的 条评论
为什么被折叠?



