[Python学习日记-52] Python 中的 copy 模块 —— shutil

devtools/2024/10/21 5:42:30/

[Python学习日记-52] Python 中的 copy 模块 —— shutil

简介

shutil 模块

简介

        在前面的学习当中,我们学习了如何在 Python 中创建文件,这个时候我们基本已经有了写程序的能力了,而有的时候我们也想使用 Python 来对文件进行更多的操作,例如修改它的权限信息、存储位置等,同时在传递程序或者提供程序下载时,我们更希望的是程序能越小越好,这样对于用户传输的带宽要求、等待时间等都会更友好,这就要用到 shutil 模块了,下面我们一起来看一看吧。

shutil 模块

        该模块是高级的文件、目录、压缩包的处理模块

一、copyfileobj()

        将文件内容拷贝到另一个文件中,语法如下

shutil.copyfileobj(src_file_obj, dest_file_obj, length)

参数说明:

  • src_file_obj:源文件对象
  • dest_file_obj:目标文件对象
  • length:可选参数,指定要复制的字节数,默认为-1,表示复制整个文件。如果指定了 length 参数,函数将在复制指定字节数后停止

演示代码如下

python">import shutilshutil.copyfileobj(open('game.json','r'),open('game_new.json','w'))

代码效果如下:

二、copyfile()

        拷贝整个文件,如果目标文件不存在则会直接创建,语法如下

shutil.copyfile(src, dst, *, follow_symlinks=True)

参数说明:

  • src: 需要复制的源文件路径
  • dst: 目标文件路径
  • follow_symlinks: 如果为 True(默认值),则复制文件时会跟踪源文件的符号链接。如果为 False,则复制源文件本身

        如果复制操作成功,则返回目标文件的路径,演示代码如下

python">import shutilshutil.copyfile("game.json","game1.json")   # 目标文件无需存在

代码效果如下:

三、copymode()

        仅拷贝权限,而内容、组、用户均不变,语法如下

shutil.copymode(src, dst)

参数说明:

  • src: 需要复制的源文件路径
  • dst: 目标文件路径

演示代码如下

python">import shutilshutil.copymode("game.json","game1.json")    # 目标文件必须存在

        该模块对于 Linux 系统中的权限操作比较好使,对于 Windows 的权限操作该模块实测并无效果。

四、copystat()

        仅拷贝状态信息,包括:mode bits,atime,mtime,flags,语法如下

shutil.copystat(src, dst, *, follow_symlinks=True)

参数说明:

  • src:需要复制权限和状态信息的源文件路径
  • dst:目标文件路径
  • follow_symlinks:如果为 True,则复制符号链接的状态信息;如果为 False,则复制符号链接本身的状态信息,默认为 True

        该函数用于将 src 的文件权限和状态信息复制到 dst 中。它会复制文件的权限位,最后访问时间,最后修改时间和用户 id/group_id,演示代码如下

python">import shutilshutil.copystat("game.json","game1.json")    # 目标文件必须存在

代码效果如下:

        在 Windows 下只能复制修改时间,该模块与 copymode() 一样,在 Linux 系统中的权限操作比较好使。

五、copy()

        拷贝文件或目录和权限,语法如下

shutil.copy(src, dst, *, follow_symlinks=True)

参数说明:

  • src:是源文件的路径
  • dst:是目标文件的路径
  • follow_symlinks:表示是否跟踪符号链接,默认为 True

        该方法是将源文件复制到目标文件,并返回目标文件的路径,演示代码如下

python">import shutilprint(shutil.copy("game.json","game1.json"))

代码输出如下:

        但它并不能复制整个目录,如果需要的话可以使用 copytree() 方法。

六、copy2()

        拷贝文件或目录和状态信息,语法如下

shutil.copy2(src, dst, *, follow_symlinks=True)

参数说明:

  • src:是源文件的路径
  • dst:是目标文件的路径
  • follow_symlinks:表示是否跟踪符号链接,默认为 True

演示代码如下

python">import shutilprint(shutil.copy2("game.json","game1.json"))

代码输出如下:

七、ignore_patterns() & copytree()

        copytree() 方法可递归的去拷贝目录,通常会配合 ignore_patterns() 方法使用,可以对不想拷贝的文件进行过滤,语法如下

shutil.copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, ignore_dangling_symlinks=False)

shutil.ignore_patterns(*patterns)

copytree() 的参数说明:

  • src:源目录的路径
  • dst:目标目录的路径
  • symlinks:如果为 True,则拷贝符号链接。默认为 False
  • ignore:配合 ignore_patterns() 使用,用于指定要忽略的文件和目录的规则。如果不指定,则默认不忽略任何文件和目录
  • copy_function:复制文件的函数。默认为 shutil.copy2(),它会复制文件的权限和其他状态信息。
  • ignore_dangling_symlinks:如果为 True,则忽略源目录中的悬挂符号链接。默认为 False。

ignore_patterns() 的参数说明:

  • patterns:是一个或多个glob模式字符串,可以使用通配符(例如 * 和 ?)来匹配文件和目录的名称

ignore_patterns() 会根据这些模式创建一个用于过滤名称的函数,并将其返回。下面我们将结合这两种方法来进行演示,演示代码如下

python">import shutilshutil.copytree("jove_test_module", "jove_test_module_copytree",ignore=shutil.ignore_patterns("*.md","top*"))

代码效果如下:

八、rmtree()

        递归的去删除整个目录,语法如下

shutil.rmtree(path, ignore_errors=False, οnerrοr=None)

参数说明:

  • path:要删除的目录路径。
  • ignore_errors:可选参数,如果设置为 True,则忽略错误,即使目录不存在也不会抛出异常。默认值为 False
  • onerror:可选参数,用于设置错误处理函数。默认值为 None,表示如果出现错误,则抛出异常

演示代码如下

python">import shutil# 删除目录及其下的所有文件和子目录
shutil.rmtree('/path/to/directory')# 忽略错误,即使目录不存在也不会抛出异常
shutil.rmtree('/path/to/directory', ignore_errors=True)# 自定义错误处理函数
def handle_error(func, path, exc_info):print(f"Error: {path} - {exc_info[1]}")shutil.rmtree('/path/to/directory', onerror=handle_error)

注意:使用该函数要格外小心,因为它会删除整个目录,包括目录下的所有文件和子目录,且无法恢复!

九、move()

        递归的去移动整个目录,它类似 Linux 中的 mv 命令,其实就是重命名,语法如下

shutil.move(src, dst, copy_function=shutil.copy2)

参数说明:

  • src:源目录的路径
  • dst:目标目录的路径
  • copy_function:可选参数,用于指定在移动文件时是否保留源文件的状态信息(例如文件的访问时间和权限)。默认为 shutil.copy2()

演示代码如下

python">import shutil# 移动文件
shutil.move('file.txt', 'new_location/file.txt')    # 目标路径的目录要先创建好# 移动目录
shutil.move('dir', 'new_location/dir')    # 目标路径的目录要先创建好

代码效果如下:

十、make_archive()

        创建压缩包并返回文件路径,例如:zip、tar,语法如下

shutil.make_archive(base_name, format, root_dir=None, base_dir=None, verbose=0, dry_run=False, owner=None, group=None, logger=None)

参数说明:

  • base_name:要创建的压缩文件的名称,包括文件路径和文件名,只是文件名时,则保存至当前目录,否则保存至指定路径。例如 data_bak ——> 保存至当前路径;C:/tmp/data_bak ——> 保存至 C:/tmp/
  • format:压缩文件的格式。可以是"zip"、"tar"、"gztar"、"bztar"或"xztar"
  • root_dir:要压缩的文件夹的路径。如果未指定,则默认为当前工作目录
  • base_dir:要包含在压缩文件中的目录的路径。如果未指定,则默认为 root_dir
  • verbose:控制输出的详细程度。0表示没有输出,1表示输出压缩过程的摘要信息,2表示输出详细的压缩过程信息
  • dry_run:如果设置为 True,则不会创建实际的压缩文件,而只是模拟压缩的过程
  • owner:压缩文件的所有者。该参数仅在 Unix/Linux 系统上有效
  • group:压缩文件的所属组。该参数仅在 Unix/Linux 系统上有效
  • logger:用于记录日志的对象,通常是 logging.Logger 对象

 演示代码如下

python">import shutil# 将  .\new_location 下的文件打包放置当前程序目录
ret = shutil.make_archive("data_bak","gztar",root_dir=r".\new_location")# 将 .\new_location 下的文件打包放置 C:\Users\Administrator\Desktop\tmp\ 目录
ret = shutil.make_archive(r"C:\Users\Administrator\Desktop\tmp\data_bak","gztar",root_dir=r".\new_location")

代码效果如下:

        其实 shutil 对压缩包的处理是调用 zipfile 和 tarfile 两个模块来进行的,下面我们也来讲一讲这两个模块的用法。

zipfile 压缩和解压缩:

python">import zipfile# 压缩
z = zipfile.ZipFile(r"C:\Users\Administrator\Desktop\test_compress.zip","w")
z.write("jove_test_module")
z.write("game.json")
z.close()# 解压缩
z = zipfile.ZipFile(r"C:\Users\Administrator\Desktop\test_compress.zip","r")
z.extractall(path=r"C:\Users\Administrator\Desktop\tmp")
z.close()

代码效果如下:

        但是会发现一个问题,ZipFile 并没有把整个目录都拷贝过来,只是把最表层的目录拷贝了过去而已,如图所示

        这与我们的设想不太一样,这个时候我们可以使用 os 模块中的 walk() 方法,来把整个目录拷贝过去,我们先来看看 os.walk() 到底如何使用先,代码如下

python">import osfor i in os.walk("./jove_test_module"):print(i)

代码输出如下:

        输出当中每一次输出都是一个元组,而元组包含三个元素,第一个是 root 目录,第二个是 root 目录下的目录,第三个是 root 目录下的文件。分析完输出的数据后就可以根据 os.walk() 来编写程序了,代码如下

python">import os
import zipfilez = zipfile.ZipFile(r'C:\Users\Administrator\Desktop\test_compress.zip','w')filelist = []
for root, dirs, files in os.walk(r"jove_test_module"):if not files:if not dirs:filelist.append(root)else:for name in files:filelist.append(os.path.join(root,name))for file in filelist:print(file)z.write(file)z.close()

代码效果与输出如下:

tarfile 压缩和解压缩:

        将目标文件打包为 tar 包,而且打包为 tar 包是只打包不压缩的,代码如下

python">import tarfile# 压缩
t = tarfile.open(r'C:\Users\Administrator\Desktop\test_compress.tar','w')
t.add("jove_test_module")
t.add(r"jove_test_module\setup.py")
t.add("game.json")
t.close()# 解压缩
t = tarfile.open(r'C:\Users\Administrator\Desktop\test_compress.tar','r')
t.extractall("./tmp",filter="fully_trusted")  # 解压整个文件
t.extract("jove_test_module/setup.py","./tmp/jove_module",filter="fully_trusted")   # 解压单个文件
t.close()

代码效果如下:

注意:tarfile 模块存在限制,为了避免解压时会出现覆盖其他文件的错误操作,这就导致了可能会出现一下报错:DeprecationWarning: Python 3.14 will, by default, filter extracted tar archives and reject files or modify their metadata. Use the filter argument to control this behavior.
  t.extractall("./tmp"),这就是由于 tarfile 的安全限制导致的,这个时候我们需要使用  filter="fully_trusted" 来放开限制

filter 参数详细可参见官方文档:tarfile — Read and write tar archive files — Python 3.12.7 documentation


http://www.ppmy.cn/devtools/127486.html

相关文章

QT 软件打包为一个单独可执行.exe文件

将 QT 应用程序打包为一个独立的可执行文件 (.exe) 以便于分发通常包括以下几个步骤。以下是详细的流程和说明: 1. 准备环境 确保已经安装了以下软件: Qt SDK:可以从 Qt 官网 下载。Qt Creator:通常包含在 Qt SDK 中。MinGW 或…

一起搭WPF架构之livechart的MVVM使用介绍

一起搭WPF架构之livechart使用介绍 前言ModelViewModelView界面设计界面后端 效果总结 前言 简单的架构搭建已经快接近尾声了,考虑设计使用图表的形式将SQLite数据库中的数据展示出来。前期已经介绍了livechart的安装,今天就详细介绍一下livechart的使用…

关于Vue脚手架

一、简介与安装 1 简介 Vue Cli 全称Vue command line interface(Vue命令行接口),俗称Vue脚手架, 是Vue官方提供的一个标准化开发工具(开发平台)。 可以帮助我们快速创建一个开发Vue项目的标准化基础架子。【集成了webpack配置】 参考官网&#xff1a…

使用 surya-ocr 进行文字识别

surya-ocr 是一个开源的 OCR 模型,个人用是免费的,商用是需要License,收费标准有些复杂,具体可以查看官网。 主要包括以下功能: 支持 90 多种语言的 OCR任何语言的行级文本检测版面分析(表格、图像、标题等…

高级java每日一道面试题-2024年10月12日-Web篇-http,servlet,tomcat 之间是什么关系?

如果有遗漏,评论区告诉我进行补充 面试官: http,servlet,tomcat 之间是什么关系? 我回答: HTTP(超文本传输协议)、Servlet 和 Tomcat 之间的关系可以这样理解:它们是构建Web应用程序的不同层次的技术。下…

帝国cms取得内容和栏目链接地址的方法

用以下2个函数解决内容页面和栏目页面链接,可有效解决更改URL显示方式(动态、静态、伪静态)不需要修改模版中的链接地址。 内容页链接地址: $infourlsys_ReturnBqTitleLink($r); $r为含“id,classid,newspath,filename,groupid,ti…

使用Diffutoon把视频转换成动漫风格,无需部署,开箱即用

无论是图片动漫转换以及视频动漫转换,我们前期也介绍过相关的模型,但是其模型输出的动漫视频不是有瑕疵,就是动漫效果不唯美,今天介绍一个modelscope社区开源的动漫风格转换模型Diffutoon。 Diffutoon模型接受视频作为输入&#x…

如何在Android中进行日志打印和调试?

在Android开发中,日志打印和调试是开发者定位问题、优化性能和提升应用质量的重要手段。以下将详细阐述如何在Android中进行日志打印和调试,包括日志工具的使用、调试技巧以及实践中的最佳实践。 一、日志工具的使用 1. Log类 Android中的日志工具类是…