第十一章 shutil模块

1. shutil模块介绍

shutil 模块是Python 内置的对文件、文件夹、压缩文件进行高级操作的模块。该模块对于多个文件的复制、删除和压缩等操作提供了非常方便的支持。如果只是对单个文件进行操作,可以使用os 模块。

说明:在使用shutil 模块时,不能复制所有文件的元数据。在POSIX 平台上,不能复制文件的所有者和组,以及访问控制表;而在Mac OS 中,不能复制文件类型和创建者;在Windows 操作系统中,不能复制文件的所有者、访问控制列表和备用数据流。

shutil 模块属于内置模块,不需要安装,直接导入即可使用。在Python 程序中使用shutil 模块,首先需要使用import 语句导入,代码如下:

import shutil

使用上面代码导入shutil 模块后,就可以使用该模块提供的属性和方法了。如果不确定该模块都提供了哪些属性和方法,可以使用Python 的内置函数dir() 获取全部方法列表,代码如下:

import shutil   		# 高级文件操作模块

print(dir(shutil))

2. chown()方法——更改给定路径的所有者用户和(或)组

chown() 方法用于更改给定路径的所有者用户和(或)组。语法格式如下:

shutil.chown(path, user=None, group=None)

参数说明:

  • path:必选参数,用于指定要操作的路径。

  • user:表示所有者,可以是系统用户名或UID,同样适用于群体。但是传递的值必须真实,否则报错“没有此用户”。

  • group :表示分组,传递的值必须真实,否则报错“没有此用户”。

  • 返回值:无。

说明:chown() 方法只适用于Unix 系统。

使用chown() 方法更改指定路径的所有者用户和组,代码如下:

import shutil                                                			# 导入高级文件操作模块

import os                                                    			# 导入os模块

from pathlib import Path

import pwd

path = os.path.join(os.getcwd(),’test.txt’)                      		# 连接路径

shutil.chown(path,user=Path(path).owner(),group=Path(path).group())		# 更改所有者用户和组07 pwd.getpwuid(os.stat(path).st_uid)[0]

3. copy()方法——复制文件到文件或目录

copy() 方法用于将单个文件复制到另一个文件或目录。语法格式如下:

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

参数说明:

  • src :字符串类型的路径,用于指定源文件。

  • dst:字符串类型的路径,用于指定目标文件或者目录。如果是目录,则将src 中的文件复制到dst 目录中。

  • follow_symlinks:命名关键字参数,表示是否遵循符号链接。值为布尔类型,默认值为True,表示复制文件;如果值为False,并且src 为软链接,将创建一个新的软链接。

  • 返回值:返回目标路径,即新创建文件的路径。

说明:在方法中,如果出现“*,”则表示其后面的参数为命名关键字参数,这是一个特殊的分隔符。在调用时,命名关键字参数必须传入参数名。

注意:使用copy() 方法复制文件时,会复制文件数据和文件的权限位,其他元数据(如文件的创建和修改时间)不会保留。要保留原始文件中的所有文件元数据,请使用copy2() 方法。

使用copy() 方法将当前目录下的test.txt 文件复制到当前目录的子目录test 中,代码如下:

import shutil                        		# 导入高级文件操作模块

print(shutil.copy(‘test.txt’,r’test/))  	# 复制文件到目录

程序运行结果如下,同时,在test 目录中多一个test.txt 文件。

test/test.txt

使用copy() 方法将当前目录下的test.txt 文件复制到当前目录的子目录test 中的bak.txt 文件中,代码如下:

import shutil                               		# 导入高级文件操作模块

print(shutil.copy(‘test.txt’,r’test/bak.txt’))   	# 复制文件到文件

说明:如果指定的目标文件存在,但是不具备写权限,那么将会抛出“PermissionError: [Errno 13]Permission denied: ‘test/bak.txt’”异常。

4. copy2()方法——复制文件到文件或目录

copy2() 方法用于将文件复制到另一个文件或目录(尝试保留文件元数据之外相同的内容)。语法格式如下:

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

参数说明:

  • src:字符串类型的路径,用于指定源文件。

  • dst:字符串类型的路径,用于指定目标文件或者目录。如果是目录,则将src 中的文件复制到dst 目录中。

  • follow_symlinks:命名关键字参数,表示是否遵循符号链接。值为布尔类型,默认值为True,表示复制文件;如果值为False,并且src 为软链接,将创建一个新的软链接。

  • 返回值:返回目标路径,即新创建文件的路径。

说明:在方法中,如果出现“*,”则表示其后面的参数为命名关键字参数,这是一个特殊的分隔符。在调用时,命名关键字参数必须传入参数名。

使用copy2() 方法将当前目录下的test.txt 文件复制到当前目录的子目录test 中,代码如下:

import shutil                        		# 导入高级文件操作模块

print(shutil.copy2(‘test.txt’,r’test/))  	# 复制文件到目录

程序运行结果如下,同时,在test 目录中多一个test.txt 文件。

test/test.txt

将当前目录下的test.txt 文件复制到当前目录的子目录test 中的bak.txt 文件中,代码如下:

import shutil                               		# 导入高级文件操作模块

print(shutil.copy2(‘test.txt’,r’test/bak.txt’))  	# 复制文件到文件

程序运行结果如下,同时,在test 目录中的bak.txt 文件的内容被替换为test.txt 文件的内容。如果指定的文件不存在,将自动创建该文件。

test/bak.txt

说明:如果指定的目标文件存在,但是不具备写权限,那么将会抛出“PermissionError: [Errno 13] Permissiondenied: ‘test/bak.txt’”异常。

分别使用copy() 方法和copy2() 方法将当前目录下的test.txt 文件复制到当前目录的子目录test 中,其中,使用copy() 方法复制的文件命名为copy.txt,使用copy2() 方法复制的文件命名为copy2.txt,代码如下:

import shutil                           		# 导入高级文件操作模块

shutil.copy(‘test.txt’,r’test/copy.txt’)     	# 使用copy()方法复制文件

shutil.copy2(‘test.txt’,r’test/copy2.txt’)   	# 使用copy2()方法复制文件

说明:运行程序,将在test 目录中自动创建copy.txt 和copy2.txt 两个文件。查看原文件test.txt 和copy.txt、copy2.txt 文件的属性,如图1 所示。从图1 中可以看出使用copy() 方法复制文件时,只复制文件和权限,但是使用copy2() 方法还会将文件的修改时间一同复制。

5. copyf ile()方法——复制文件内容

copyfile() 方法用于复制文件内容到目标文件,并且返回目标文件的路径。语法格式如下:

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

参数说明:

  • src:字符串类型的路径,用于指定源文件。

  • dst:字符串类型的路径,用于指定目标文件,必须拥有可写权限。如果dst不存在,则自动创建。

  • follow_symlinks:命名关键字参数,表示是否遵循符号链接。值为布尔类型,默认值为True,表示复制文件;如果值为False,并且src 为软链接,将创建一个新的软链接。

  • 返回值:返回目标文件的路径,即dst参数的值。

注意:如果src 和dst 指向同一个文件,则会抛出SameFileError 异常。

说明:在方法中,如果出现“*,”则表示其后面的参数为命名关键字参数,这是一个特殊的分隔符。在调用时,命名关键字参数必须传入参数名。

假如当前路径上有一个名称为test.txt 的文本文件,使用copyfile() 方法分别在当前目录和E盘根目录下各复制一个名称为test2.txt 的文件,内容为test.txt 文件的内容,代码如下:

import shutil                               			# 导入高级文件操作模块

print(shutil.copyfile(‘test.txt’,’test2.txt’))   		# 复制文件

print(shutil.copyfile(‘test.txt’,’E:/test2.txt’))		# 复制文件

运行上面的代码,将显示以下内容。同时,将在当前目录下创建test2.txt 文件,在E:/ 目录下也创建test2.txt 文件,这两个文件的内容都和源文件test.txt 相同。如果目标已经文件存在,则替换已有内容。

test2.txt

E:/test2.txt

使用copyfile() 方法向不同位置复制文件,并且处理可能出现的异常,代码如下:

import shutil                               			# 导入高级文件操作模块

try:

	shutil.copyfile(‘E:/test2.txt’,’test.txt’)   		# 目标文件为只读属性

	except Exception as e:

	print(‘出错了!',e)

	try:

		shutil.copyfile(‘E:/test3.txt’,’E:/test.txt’) 	# 源文件不存在

		except Exception as e:

		print(‘出错了!',e)

	try:

		shutil.copyfile(‘E:/test2.txt’,’E:/test2.txt’)	# 源文件和目标文件相同

		except Exception as e:

		print(‘出错了!',e)

6. copyf ileobj()方法——复制文件对象

copyfileobj() 方法用于复制file-like 对象的内容到目标文件对象。语法格式如下:

shutil.copyfileobj(fsrc, fdst[, length])

参数说明:

  • fsrc :源文件对象。可以通过Python 内置函数open() 创建。

  • fdst:目标文件对象。如果fdst不存在,则自动创建,也可以通过Python内置函数open()创建。

  • length:可选参数,用于指定缓冲区大小。如果是负数,则表示直接复制,不循环遍历块中的源数据。默认缓冲区大小为“16*1024”字节。

  • 返回值:无。

说明:绝对路径是指在使用文件时指定文件的实际路径,它不依赖于当前工作目录。

假如当前路径上有一个名称为test.txt 的文本文件,使用copyfileobj() 方法创建一个该文件的副本,代码如下:

import shutil                                         				# 导入高级文件操作模块

shutil.copyfileobj(open(‘test.txt’,’r’),open(‘test1.txt’,’w’)) 		# 复制文件对象

分别通过copyfileobj() 和copyfile() 方法复制大文件,并且在进行复制时,分别记录各自的所用时间,代码如下:

import shutil                                  		# 导入高级文件操作模块

import datetime                                		# 导入日期时间模块

st = datetime.datetime.now()                     	# 获取开始时间

print(‘通过copyfileobj()方法复制')

with open(r’H:/temp.rar’,’rb’) as src:              # 打开源文件

with open(r’H:/temp/temp.rar’,’wb’) as dst:      	# 创建目标文件

shutil.copyfileobj(src,dst,1024)           			# 分段复制

et = datetime.datetime.now()                     	# 获取结束时间

print(‘复制完成。用时:',et-st)

st = datetime.datetime.now()                     	# 获取开始时间

print(‘通过copyfile()方法复制')

shutil.copyfile(r’H:/temp.rar’,’H:/temp/temp2.rar’)

et = datetime.datetime.now()                    	# 获取结束时间

print(‘复制完成。用时:',et-st)

如果源文件temp.rar 为1GB,程序运行结果如下:

通过copyfileobj()方法复制
复制完成。用时: 0:00:04.215191
通过copyfile()方法复制
复制完成。用时: 0:00:09.358080

如果源文件temp.rar 为40MB,程序运行结果如下:

通过copyfileobj()方法复制
复制完成。用时: 0:00:00.131919
通过copyfile()方法复制
复制完成。用时: 0:00:00.070959

说明:从上面的运行结果中可以看出:当复制大文件时,采用copyfileobj() 方法比copyfile() 方法要快一些;而对于小文件,则使用copyfile() 方法会快一些。所以,建议在复制大文件时,采用copyfileobj() 方法,小文件采用copyfile() 方法。

7. copymode()方法——复制权限位

copymode() 方法用于将一个文件的权限复制给另一个文件。语法格式如下:

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

参数说明:

  • src :字符串类型的路径,用于指定源文件。

  • dst:字符串类型的路径,用于指定目标文件。

  • follow_symlinks:命名关键字参数,表示是否遵循符号链接。值为布尔类型,默认值为True,表示复制权限位;如果值为False,并且src 为软链接,将创建一个新的软链接。

  • 返回值:返回None。

说明:在方法中,如果出现“*,”则表示其后面的参数为命名关键字参数,这是一个特殊的分隔符。在调用时,命名关键字参数必须传入参数名。

为test.txt 设置只读权限,然后再使用copymode() 方法将test.txt 文件的权限位复制给test1.txt 文件,代码如下:

import shutil                        		# 导入高级文件操作模块

shutil.copymode(‘test.txt’,’test1.txt’)  	# 复制文件权限

8. copystat()方法——复制文件信息

shutil 模块的copystat() 方法用于复制权限、最后访问时间、最后修改时间等文件信息。语法格式如下:

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

参数说明:

  • src:字符串类型的路径,用于指定源文件。

  • dst:字符串类型的路径,用于指定目标文件。

  • follow_symlinks:命名关键字参数,表示是否跟踪符号链接。值为布尔类型,默认值为True,表示复制权限、最后访问时间等信息;如果值为False,并且src 为软链接,将创建一个新的软链接。

  • 返回值:返回None。

说明:在方法中,如果出现“*,”则表示其后面的参数为命名关键字参数,这是一个特殊的分隔符。在调用时,命名关键字参数必须传入参数名。

使用copystat() 方法将test.txt 的权限位、最后修改时间等复制给test1.txt,代码如下:

import shutil                        		# 导入高级文件操作模块

shutil.copystat(‘test.txt’,’test1.txt’)  	# 复制文件权限位、最后修改时间等信息

9. copytree()方法——递归复制整个目录树

copytree() 方法用于递归复制以指定目录为根的整个目录树,返回目标目录。语法格式如下:

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

参数说明:

  • src :字符串类型的路径,用于指定源目录,并且必须是一个目录,不能是文件。

  • dst:字符串类型的路径,用于指定目标目录。该目录必须是一个不存在的目录,否则将抛出FileExistsError 异常。

  • symlinks:值为布尔类型,表示是否遵循符号链接。默认值为True,表示复制文件;如果值为False,并且src 为软链接,将创建一个新的软链接。

  • ignore :可选参数,表示一个可调用对象,用于筛选特别的文件。其参数值为目录名称和目录内容的列表。

  • copy_function:表示一个可调用对象,用于复制文件。其参数值为源路径和目标路径。

  • ignore_dangling_symlinks:表示是否忽略symlinks。如果值为True,则忽略symlinks 参数;值为False 时,由于源文件不存在而产生异常。对于不支持os.symlink() 的平台,此参数无任何影响。

  • 返回值:返回目标目录。

使用copytree() 方法将包括子目录的目录全部复制到另一个目录中,代码如下:

import shutil                               		# 导入高级文件操作模块

print(shutil.copytree(r’H:/code’,r’H:/code1’))   	# 递归复制目录树

运行程序,将显示以下运行结果,同时H:/code 目录下的子目录及文件都被复制到H:/code1 目录下。

H:/code1

首先判断指定的源路径是目录还是文件,如果是目录,则使用copytree() 方法进行复制,否则使用copy() 方法进行复制,代码如下:

import shutil                        						# 导入高级文件操作模块

import os                           						# 文件与操作系统相关模块

src = r’H:/code’                                           	# 源路径1

src2 = r’E:/cba.txt’                                    	# 源路径2

dst = r’H:/code2’                                         	# 目标路径

if os.path.isdir(src):

	print(shutil.copytree(src ,dst))   						# 递归复制目录树

else:

	print(shutil.copyfile(src ,dst))   						# 复制文件

if os.path.isdir(src2):

	print(shutil.copytree(src2 ,dst)) 						# 递归复制目录树

else:

	print(shutil.copy(src2 ,dst))     						# 复制文件

10. disk_usage()方法——获取指定路径所在磁盘的使用情况

disk_usage() 方法用于获取指定路径所在磁盘的使用情况,包括总空间、已使用空间和空闲空间等信息,该方法以字节为单位。语法格式如下:

shutil.disk_usage(path)

参数说明:

  • path:表示文件或目录的路径。在Windows 系统中必须是目录路径,在Linux 系统中可以是文件路径或目录路径。

  • 返回值:返回保存磁盘使用情况的命名元组,其中包括total(总空间)、used(已使用空间)和free(空闲空间)3 个属性。命名元组可以通过索引元素访问,也可以通过属性名称访问。

使用disk_usage() 方法获取指定目录(E:/mr/test/pdf)所在磁盘E 盘的使用情况,代码如下:

import shutil                               		# 导入高级文件操作模块

result = shutil.disk_usage(r’E:/mr/test/pdf’)   	# 获取E盘的使用情况

print(result)

程序运行结果如下:

usage(total=332860596224, used=284235145216, free=48625451008)

使用disk_usage() 方法获取指定目录(E:/mr/test/pdf)所在磁盘E 盘的使用情况,并把得到字节数格式化,代码如下:

import shutil                                                    	# 导入高级文件操作模块

def formatByte(number):

    """格式化文件大小的函数

	number:要格式化的字节数

    """

for (scale,label) in [(1024*1024*1024,’GB’),(1024*1024,’MB’),(1024,’KB’)]:

	if number>= scale:                                            	# 如果文件大小大于等于1KB

		return%.2f %s’ %(number*1.0/scale,label)

	elif number == 1:                                             	# 如果文件大小为1字节

		return1 字节'

	else:                                                       	# 处理小于1KB的情况

		byte =%.2f’ % (number or 0)

		# 去掉结尾的.00,并且加上单位“字节”

		return (byte[:-3] if byte.endswith(.00) else byte)+’ 字节'
	

result = shutil.disk_usage(r’E:\mr\test\pdf’)                  		# 获取E盘的使用情况

print(‘总空间:',formatByte(result.total))

print(‘已用空间:',formatByte(result.used))

print(‘空闲空间:',formatByte(result.free))

11. get_archive_formats()方法——获取支持的压缩格式

get_archive_formats() 方法用于返回当前系统支持的(已注册)压缩格式列表。语法格式如下:

shutil.get_archive_formats()

参数说明:

  • 返回值:返回保存支持的压缩格式的列表。该列表的每个元素都是元组(第一个元素是格式名称,第二个元素是描述信息)。

使用get_archive_formats() 方法获取并显示支持的压缩格式列表,代码如下:

import shutil                        	# 导入高级文件操作模块

print(shutil.get_archive_formats())    	# 打印支持的压缩格式

程序运行结果如下:

[('bztar', "bzip2'ed tar-file"), ('gztar', "gzip'ed tar-file"), ('tar', 'uncompressed tarfile'), ('xztar', "xz'ed tar-file"), ('zip', 'ZIP file')]

使用get_archive_formats() 方法判断输入的文件格式是否为支持的压缩格式,代码如下:

import shutil                        			# 导入高级文件操作模块

ff = input(‘请输入要判断的文件格式:')

for f in shutil.get_archive_formats(): 			# 获取系统支持的压缩格式

	if ff == f[0]:

	print(ff,’为系统支持的压缩格式!')

	break                         				# 中止循环

12. get_terminal_size()方法——获取终端窗口的大小

get_terminal_size() 方法用于获取终端窗口的大小。语法格式如下:

shutil.get_terminal_size(fallback=(columns, lines))

参数说明:

  • columns:表示列数。如果系统不支持查询,或者未连接到终端,则使用此处指定的列数。默认值为80。

  • lines:表示行数。如果系统不支持查询,或者未连接到终端,则使用此处指定的行数。默认值为24。

  • 返回值:返回os.terminal_size类型的命名元组。

使用get_terminal_size() 方法获取终端窗口的大小,并且设置默认值为400 列、300 行,代码如下:

import shutil      				# 导入高级文件操作模块

print(shutil.get_terminal_size(fallback=(400,300)))

13. get_unpack_formats()方法——获取支持的解压缩格式

get_unpack_formats() 方法用于返回当前系统支持的(已注册)解压缩格式列表。语法格式如下:

shutil.get_unpack_formats()

参数说明:

  • 返回值:返回支持的解压缩格式列表。该列表的每个元素都是元组(第一个元素是格式名称,第二个元素是扩展名列表,第三个元素是描述信息)。

使用get_unpack_formats() 方法获取并显示支持的解压缩格式列表,代码如下:

import shutil                    		# 导入高级文件操作模块

print(shutil.get_unpack_formats()) 		# 打印支持的解压缩格式

14. ignore_patterns()方法——提供glob(通配符)功能

ignore_patterns() 方法是一个工厂函数,用于为shutil.copytree() 方法的ignore 参数提供值,该值在复制过程中将被忽略,是一个基于glob(通配符)模式的callable。语法格式如下:

shutil.ignore_patterns(*patterns)

参数说明:

  • l *patterns:表示指定通配符,可以有多个,使用英文半角的逗号“,”进行分隔。

  • 返回值:返回相对于当前目录的一系列目录和文件名,这些值在复制过程中将被忽略。

递归复制目录树,指定忽略全部扩展名为.docx 的文件,以及以l 开头的全部文件,代码如下:

import shutil  				# 导入高级文件操作模块

# 复制目录树(忽略全部.docx文件和以l开头的全部文件)

shutil.copytree(r’E:\mr\test\pdf’,r’E:\mr\test\pdf1’,ignore=shutil.ignore_patterns(*.docx’,’l*))

15. make_archive()方法——创建压缩文件并返回文件路径

make_archive() 方法用于创建压缩文件并返回文件路径。语法格式如下:

shutil.make_archive(base_name, format[, root_dir[, base_dir[, verbose[, dry_run[,owner[, group[, logger]]]]]]])

参数说明:

  • base_name:表示压缩包的文件名(不包括扩展名),也可以包括路径。如果只写文件名时,保存到当前目录,否则保存到指定路径。

  • format :表示压缩包格式,如zip、tar、bztar、gztar 等。

  • root_dir :表示将要被压缩的目录路径(默认为当前目录)。

  • base_dir:表示开始压缩的目录,即压缩文件中所有文件和目录的公共前缀。默认为当前目录。

  • verbose:已弃用。

  • dry_run :表示是否创建存档。如果dry_run 为true,则不会创建存档,但会将执行的操作记录到logger。

  • owner :可选参数,用于指定用户,默认为当前用户。

  • group :可选参数,用于指定组,默认为当前组。

  • logger :用于记录日志,通常为logging.Logger对象。

  • 返回值:返回压缩文件名称。

说明:make_archive() 方法依赖于zipfile 和tarfile 模块。

使用make_archive() 方法将指定目录下的全部文件压缩到一个.zip 文件中,并保存到当前目录下,代码如下:

import shutil                                                    			# 导入高级文件操作模块

print(shutil.make_archive(‘tempzip’,zip,root_dir= r’E:/mr/test/pdf’))   	# 压缩文件

16. move()方法——移动文件或目录

move() 方法用于将文件或目录移动到目标目录。如果移动到了不同的文件系统中,将递归地复制源目录。语法格式如下:

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

参数说明:

  • src:字符串类型的路径,用于指定要移动的源文件或目录。

  • dst:字符串类型的路径,用于指定目标目录。该目录必须是一个不存在的目录,否则将抛出FileExistsError 异常。

  • copy_function:表示一个可调用对象,用于复制文件。其参数值为源路径和目标路径。

  • 返回值:返回目标目录。

使用move() 方法将包括子目录的目录(包含子目录和文件)移动到另一个目录下,代码如下:

import shutil                           			# 导入高级文件操作模块

print(shutil.move(r’H:/code/,r’H:/code1/)) 		# 移动目录

17. register_archive_format()方法——注册压缩文件格式

register_archive_format() 方法用于注册一个压缩文件格式。语法格式如下:

shutil.register_archive_format(name, function[, extra_args[, description]])

参数说明:

  • name:表示格式名称。

  • function :用于指定压缩文档时可调用的函数。该函数需要接收base_name、base_dir、owner、group、dry_run 和logger 几个参数。

  • extra_args:可选参数,用于指定额外参数,参数值为列表,每个列表元素都是一个“(name,value)”形式的元组。

  • description:可选参数,用于指定说明信息。默认值为空字符串。

  • 返回值:无。

在Windows 系统中定义一个自己的压缩文件格式mrzip,并且获取支持的压缩格式输出,然后再使用该格式创建一个压缩文件,代码如下:

import shutil                                             			# 导入高级文件操作模块

import os                                                			# 导入os模块

def mrfunc(base_name, base_dir,compress, owner = ‘‘,group = ‘‘, dry_run=0, logger=None):

           import zipfile                                        	# 导入zipfile模块

           zip_filename = base_name + compress                     	# 组合压缩文件的名称

           archive_dir = os.path.dirname(base_name)                 # 获取压缩文件的目录

           if archive_dir and not os.path.exists(archive_dir):      # 如果指定的路径不存在

                 if logger is not None:

                       logger.info(“creating %s”, archive_dir)

                 if not dry_run:

                      os.makedirs(archive_dir)                      # 创建目录

           if logger is not None:                                 	# 如果日志信息不为空

                 logger.info(“creating ‘%s’ and adding ‘%s’ to it”,

                                  zip_filename, base_dir)

            if not dry_run:

                 # 压缩文件

                 with zipfile.ZipFile(zip_filename, “w”,

                                               compression=zipfile.ZIP_DEFLATED) as zf:

                       path = os.path.normpath(base_dir)

                       if path != os.curdir:

                                  zf.write(path, path)

                                  if logger is not None:

                                       logger.info(“adding ‘%s’”, path)

                       for dirpath, dirnames, filenames in os.walk(base_dir):

                              for name in sorted(dirnames):

                                    path = os.path.normpath(os.path.join(dirpath, name))

                                    zf.write(path, path)

                                    if logger is not None:

                                            logger.info(“adding ‘%s’”, path)

                              for name in filenames:

                                       path = os.path.normpath(os.path.join(dirpath, name))

                                       if os.path.isfile(path):

                                             zf.write(path, path)

                                          if logger is not None:

                                                   logger.info(“adding ‘%s’”, path)

                 return zip_filename                                    				# 返回压缩文件名

shutil.register_archive_format(‘mrzip’,mrfunc,[(‘compress’,.mrzip’)],’自定义文件格式’)

print(shutil.get_archive_formats())                                						# 打印支持的压缩格式

print(shutil.make_archive(‘tempzip’,’mrzip’,root_dir= r’E:/mr/test/pdf’))				# 压缩文件

程序运行结果如下:

[('bztar', "bzip2'ed tar-file"), ('gztar', "gzip'ed tar-file"), ('mrzip', '自定义文件格式'),('tar', 'uncompressed tar file'), ('xztar', "xz'ed tar-file"), ('zip', 'ZIP file')]G:\Python\PycharmProjects\dream\tempzip.mrzip

说明:在获取系统支持的压缩文件格式列表中,可以看到新创建的压缩文件格式mrzip。

18. register_unpack_format()方法——注册解压缩文件格式

register_unpack_format() 方法用于注册解压缩文件格式。语法格式如下:

shutil.register_unpack_format(name, extensions, function[, extra_args[, description]])

参数说明:

  • name:表示格式名称。

  • extensions:表示与格式名称相对应的扩展名列表。

  • function :用于指定解压缩文档时可调用的函数。该函数需要接收base_name、base_dir、owner、group、dry_run 和logger 几个参数。

  • extra_args:可选参数,用于指定额外参数,参数值为列表,每个列表元素都是一个“(name,value)”形式的元组。

  • description:可选参数,用于指定说明信息。默认值为空字符串。该参数值将被get_unpack_formats() 方法返回。

  • 返回值:无。

在Windows 系统中定义一个自己的解压缩文件格式mrzip,并且获取支持的解压缩格式输出,代码如下:

import shutil                                                    		# 导入高级文件操作模块

import os                                                       		# 导入os模块

def mrfunc(base_name, base_dir,compress, owner = ‘‘,group = ‘‘, dry_run=0, logger=None):

	import zipfile                                              		# 导入zipfile模块

	zip_filename = base_name + compress                            		# 组合解压缩文件的名称

	archive_dir = os.path.dirname(base_name)                       		# 获取解压缩文件的目录

	if archive_dir and not os.path.exists(archive_dir):              	# 如果指定的路径不存在

		if logger is not None:

			logger.info(“creating %s”, archive_dir)

		if not dry_run:

			os.makedirs(archive_dir)                               		# 创建目录

		if logger is not None:                                       	# 如果日志信息不为空

			logger.info(“creating ‘%s’ and adding ‘%s’ to it”,

			zip_filename, base_dir)

		if not dry_run:

			# 解压缩文件

			with zipfile.ZipFile(zip_filename, “w”,compression=zipfile.ZIP_DEFLATED) as zf:

				path = os.path.normpath(base_dir)

				if path != os.curdir:

					zf.write(path, path)

				if logger is not None:

					logger.info(“adding ‘%s’”, path)

				for dirpath, dirnames, filenames in os.walk(base_dir):

					for name in sorted(dirnames):

						path = os.path.normpath(os.path.join(dirpath, name))

						zf.write(path, path)

				if logger is not None:

					logger.info(“adding ‘%s’”, path)

				for name in filenames:

					path = os.path.normpath(os.path.join(dirpath, name))

					if os.path.isfile(path):

						zf.write(path, path)

				if logger is not None:

					logger.info(“adding ‘%s’”, path)

					return zip_filename                               # 返回解压缩文件名


shutil.register_unpack_format(‘mrzip’,[.mrzip’],mrfunc,[(‘compress’,.mrzip’)],’自定义文件格式’)
print(shutil.get_unpack_formats())                                    # 打印支持的解压缩格式

程序运行结果如下:

[('bztar', ['.tar.bz2', '.tbz2'], "bzip2'ed tar-file"), ('gztar', ['.tar.gz', '.tgz'], "gzip'edtar-file"), ('mrzip', ['.mrzip'], '自定义文件格式'), ('tar', ['.tar'], 'uncompressed tar file'),('xztar', ['.tar.xz', '.txz'], "xz'ed tar-file"), ('zip', ['.zip'], 'ZIP file')]

19. rmtree()方法——删除整个目录树

rmtree() 方法用于删除整个目录树。语法格式如下:

shutil.rmtree(path, ignore_errors=False, onerror=None)

参数说明:

  • path:字符串类型的路径,用于指定要删除的目录,并且必须是一个目录,不能是文件。

  • ignore_errors :用于指定是否忽略错误,如果值为True,表示忽略操作过程中出现的错误。默认值为False,表示不忽略错误。

v onerror :用于指定错误处理函数。该函数接收fun(c 引发异常的函数)、path(传递到函数的路径)和excinfo(返回的异常信息)三个参数。如果onerror 参数被省略,则发生错误时,会给出提示。

  • 返回值:返回None。

使用rmtree() 方法将包括子目录的目录(包含子目录和文件)删除,代码如下:

import shutil                    			# 导入高级文件操作模块

print(shutil.rmtree(r’H:/code1’))   		# 递归删除目录树

20. unpack_archive()方法——解压缩文件

unpack_archive() 方法用于将压缩文件解压缩。语法格式如下:

shutil.unpack_archive(filename[, extract_dir[, format]])

参数说明:

  • file_name:表示压缩文件名路径。

  • extract_dir:表示解压缩文件的目标路径。如果未指定,则使用当前工作目录。

  • format :表示压缩包格式,如zip、tar、bztar、gztar 等,也可以是调用shutil.register_unpack_format() 方法注册的任何其他格式。如果未提供,将使用压缩文件扩展名,并查看是否为该扩展名注册了解包器。如果没有找到,将抛出ValueError 异常。

  • 返回值:返回None。

说明:unpack_archive() 方法依赖于zipfile 和tarfile 模块。

使用unpack_archive() 方法将当前路径下的.zip 文件解压缩到指定目录,代码如下:

import shutil                                                				# 导入高级文件操作模块

print(shutil.unpack_archive(‘tempzip.zip,r’E:/mr/test/pdf1’,zip)) 		# 解压缩文件

21. unregister_archive_format()方法——注销压缩文件格式

unregister_archive_format() 方法用于注销已经创建的压缩文件格式。语法格式如下:

shutil.unregister_archive_format(name)

参数说明:

  • name:表示要注销的压缩文件格式名称。

  • 返回值:无。

在执行注销压缩文件格式前,需要先注册一个压缩文件格式,然后再使用unregister_archive_format() 方法注销该文件格式。这里在注册后先输出支持的压缩文件格式,再进行注销,注销后再重新获取支持的压缩文件格式,方便进行对比,代码如下:

……                                     			# 省略注册压缩文件格式的代码

print(‘注册后:’)

print(shutil.get_archive_formats())       		# 打印支持的压缩格式

print(‘注销后:’)

shutil.unregister_archive_format(‘mrzip’)

print(shutil.get_archive_formats())       		# 打印支持的压缩格式

22. unregister_unpack_format()方法——注销解压缩文件格式

unregister_unpack_format() 方法用于注销已经注册的解压缩文件格式。语法格式如下:

shutil.unregister_unpack_format(name)

参数说明:

  • name:表示要注销的解压缩文件格式名称。

  • 返回值:无。

在执行注销解压缩文件格式前,需要先注册一个解压缩文件格式,然后再使用unregister_unpack_format() 方法注销该文件格式。这里在注册后先输出支持的解压缩文件格式,再进行注销,注销后再重新获取支持的解压缩文件格式,方便进行对比,代码如下:

……                                     			# 省略注册解压缩文件格式的代码

print(‘注册后:')

shutil.register_unpack_format(‘mrzip’,[.mrzip’],mrfunc,[(‘compress’,.mrzip’)],’自定义文件格式')

print(shutil.get_unpack_formats())        		# 打印支持的解压缩格式

print(‘注销后:')

shutil.unregister_unpack_format(‘mrzip’)    	# 注销解压缩文件格式

print(shutil.get_unpack_formats())        		# 打印支持的解压缩格式

23. which()方法——获取可执行文件的路径

which() 方法用于获取指定的CMD 命令的可执行文件的路径。语法格式如下:

shutil.which(cmd, mode=os.F_OK | os.X_OK, path=None)

参数说明:

  • cmd:用于指定CMD 命令。如果调用了给定的cmd,该文件将运行;如果没有调用cmd,则返回None。

  • mode:用于指定需传递的权限掩码。指定为os.F_OK,表示测试路径是否存在;指定为os.X_OK,表示测试路径是否可执行。

  • path:用于指定查找CMD 命令的路径,如果不指定,则在环境变量中查找。在Windows 系统中,无论使用默认路径还是指定路径,当前目录始终都会添加到路径中,这是命令Shell在查找可执行文件时使用的行为。

  • 返回值:无。

使用which() 方法获取在CMD 命令行窗口中执行Python 命令时,对应的可执行文件的路径并输出,代码如下:

import shutil                                   		# 导入高级文件操作模块

print(shutil.which(‘python’))                     		# 执行CMD命令

print(shutil.which(‘python’,path = r’E:/python/))   	# 执行CMD命令

程序运行结果如下:

C:\Python\Python37\python.EXE

E:/python/python.EXE

使用which() 方法获取Windows 10 系统自带的画图程序的路径,并且使用os.execv() 方法打开画图程序,代码如下:

import shutil                        		# 导入高级文件操作模块

import os                           		# 导入文件与操作系统相关模块

paint = shutil.which(‘mspaint’)        		# 获取Windows 10系统中的画图软件的路径

os.execv(paint,[/])                 		# 执行系统自带的画图程序

你可能感兴趣的:(Python,笔记(常用模块),python,开发语言)