python编程快速上手实践项目答案_python编程快速上手之第9章实践项目参考答案...

本章介介绍了shutil,zipfile模块的使用,我们先来认识一下这2个模块吧。

一.shutil模块

shutil模块主要用于对文件或文件夹进行处理,包括:复制,移动,改名和删除文件,在shutil模块中主要以下这么几个函数:

1.复制文件和文件夹

shutil模块提供了2个函数:shutil.copy()和shutil.copytree()

shutil.copy的语法格式:

copy(src, dst)

作用:

将src处的文件复制到dst路径中去,其中src,dst都是字符串形式的路径。如果dst是一个文件名,它将作为被复制文件的新名字,相当于把原路径的文件复制到新路径并改名。

举例:

将/etc/my.cnf 复制到/root/mysql中

In [12]: import shutil

In [13]: shutil.copy('/etc/my.cnf','/root/mysql/')

Out[13]: '/root/mysql/my.cnf'In [15]: ll /root/mysql/total4

-rw-r--r--. 1 root 960 Apr 22 16:57 my.cnf

将/etc/my.cnf复制到/root/mysql并改名为mysql.cnf

In [16]: shutil.copy('/etc/my.cnf','/root/mysql/mysql.cnf')

Out[16]: '/root/mysql/mysql.cnf'In [17]: ll /root/mysql/total8

-rw-r--r--. 1 root 960 Apr 22 16:57my.cnf-rw-r--r--. 1 root 960 Apr 22 17:00 mysql.cnf

shutil.copytree的语法格式:

copytree(src, dst)

作用:

复制整个文件夹。将src处的文件夹,包括它的所有文件和子文件夹,复制到路径dst处的文件夹。返回一个新复制的文件夹路径的字符串。

举例:

In [20]: shutil.copytree('/etc/yum.repos.d','/root/repo.back')

Out[20]: '/root/repo.back'In [21]: ll /root/drwxr-xr-x. 2 root 4096 Apr 23 2017 repo.back/drwxr-xr-x. 2 root 4096 Apr 23 2017 repo.bak/

注意:dst必须是一个系统中不存在目录,不然会报错:

In [20]: shutil.copytree('/etc/yum.repos.d','/root/repo.bak')

FileExistsError: [Errno 17] File exists: '/root/repo.bak'

2.文件和文件夹的移动和改名

shutil.move()

语法格式:

move(stc,dst)

作用:

将路径stc处的文件夹移动到路径dst,并返回新位置的绝对路径的字符串。

举例:

将/root/目录下的a.txt移动到/root/test/目录中

In [26]: shutil.move('/root/a.txt','/root/test/')

Out[26]: '/root/test/a.txt'In [27]: ll /root/test

total4

-rw-r--r--. 1 root 6 Apr 22 17:30 a.txt

注意:

如果dst指向一个文件夹,src文件将移动到dst中,并保持原来的文件名,前提是dst必须是系统中已经存在的目录。

如果目标文件中已存在相同名称的文件将被覆盖,需要注意。

3.删除文件和文件夹

在os模块中:

os.remove(path)可以删除一个文件

os.rmdir(path)可以删除一个空文件夹。

在shutil模块中:

shutil.rmtree(path)可以删除一个文件夹及其所有的内容。

语法格式:

os.rmdir(path)

shutil.rmtree(path)

举例:

1 In [34]: os.remove('/root/test/a.txt')2

3 In [35]: ll /root/test/

4 total 0

5

6 In [36]: shutil.move('/root/CentOS-Base.repo','/root/test/')7 Out[36]: '/root/test/CentOS-Base.repo'

8

9 In [37]: ll test10 total 4

11 -rw-r--r--. 1 root 2573 Apr 23 2017 CentOS-Base.repo12

13 In [38]: shutil.rmtree('/root/test')14

15 In [39]: ll16 total 12

17 -rw-------. 1 root 1468 Apr 16 21:03 anaconda-ks.cfg18 drwxr-xr-x. 2 root 57 Apr 23 2017 download/

19 drwxr-xr-x. 2 root 37 Apr 22 17:00 mysql/

20 drwxr-xr-x. 6 root 95 Apr 16 21:58 py34/

21 drwxr-xr-x. 3 root 18 Apr 16 23:01 python/

22 drwxr-xr-x. 2 root 4096 Apr 23 2017 repo.back/

23 drwxr-xr-x. 2 root 4096 Apr 23 2017 repo.bak/

注意:

以上的删除都是永久的删除。为了安全起见最好使用send2trash第三方模块,它会将删除的文件放入回收站。在python3中已集成了这个模块。

send2trash用法:

import send2trash

send2trash(path)

二.遍历目录树

对文件的处理,尤其是批量操作就不得不对目录进行遍历。在python中os模块中的os.walk()函数就可以做到。

这个函数会递归遍历指定目录及子目录,返回一个3元组信息:当前目录名,子目录名,文件名,不包括 . 和 ..

常见用法:

#!/usr/bin/env python3.4#coding:utf-8

importosfor foldName,subfolders,filenames in os.walk('/root/'):print('The current folder is:' +foldName)for subfolder insubfolders:print('subfolder of' + foldName + ':' +subfolder)for filename infilenames:print('file inside' + foldName + ':' +filename)print('')

三.实践项目参考答案

1 #!/usr/bin/env python3.4

2 #coding:utf-8

3 importos4 importshutil5 importsend2trash6

7 #9.8.1

8 #拷贝指定格式文件到指定目录,下面程序是将/etc目录下所的.conf文件拷贝到/root/test/目录里。

9 src = '/etc/'

10 dst = '/root/test/'

11 ftype = '.conf'

12 count =013 for filename inos.listdir(src):14 iffilename.endswith(ftype):15 shutil.copy(src +filename,dst)16 count += 1

17 print('文件' + src + filename + '\t被拷贝到--->' + dst + '目录下')18 print("该目录下所有的" + ftype + "文件已被拷贝到" + dst + "目录下")19 print('共拷贝了' + str(count) + '个文件')20

21 #9.8.2

22 #搜索指定目录下大于100M的文件,打印出来并删除

23 #可以手动创建一个指定大小的空文件做试验

24 #dd if=/dev/zero of=hello.txt bs=100M count=1

25 for foldname,subfolders,filenames inos.walk(dst):26 for files infilenames:27 if os.path.getsize(dst + files) / 1024 /1024 > 100:28 print('大于100M的文件有:' + files + ' ' + str(os.path.getsize(dst + files) / 1024 / 1024) +'Mb')29 send2trash.send2trash(dst +files)

9.8.3

假设test文件夹下有如下文件,文件是以spam开头加上数字编号,但是编号并不连续有缺失,而且有的并不包含数字,我们需要找出不符合文件名的文件并重新命名成连续编号的文件名。

(py34) [root@master test]#ls

spam002.txt spam004.txt spam006.txt spam008.txt spam999.txt

spam003.txt spam005.txt spam007.txt spam011.txt spamkkdf.txt

参考代码如下:

1 #!/usr/bin/env python3.4

2 #coding:utf-8

3 importre4 importos5 fdir = '/root/python/py-9/test/'

6 fdir_list =os.listdir(fdir)7 fdir_count =len(fdir_list)8 print(fdir_list)9 print('该目录下共有 %d 个文件' %fdir_count)10 f_pre = 'spam'

11 f_num =[]12 f_end = '.txt'

13 fs_list =[]14 #这里只假定文件数量小100的情况

15 for i in range(1,fdir_count + 1):16 if i < 10:17 f_name = f_pre + '00' + str(i) +f_end18 f_num.append('00' +str(i))19 fs_list.append(f_name)20 else:21 f_name = f_pre + '0' + str(i) +f_end22 f_num.append('0' +str(i))23 fs_list.append(f_name)24 max_f_num =max(f_num)25 print('该目录下文件最大的编号应该是: %s' %max_f_num)26 print('正确的文件名应该是:')27 print(fs_list)28

29 #使用正则表达式搜索目录中已有编号的文件并存入列表yf_num中

30 re_num = '\d{3}'

31 yf_num = re.findall(f_pre + re_num + f_end,' '.join(fdir_list))32 ra_num = re.findall(re_num,' '.join(fdir_list))33 print('目录中已有编号文件:\n%s' %yf_num)34

35 #fq_list为目录中缺失编号的文件名列表

36 #fx_list为当前目录中需要修改名称的文件列表

37 fq_list =[]38 fx_list =[]39 #定位缺失的编号文件并放入列表中

40 for a infs_list:41 if a not inyf_num:42 fq_list.append(a)43 print('缺少的文件编号是:\n%s' %fq_list)44

45 #查找目录中没有编号或不正连续的编号文件并放入列表中

46 for f_rename infdir_list:47 if f_rename not infs_list:48 fx_list.append(f_rename)49 print('需要修改的文件名有:\n%s' %fx_list)50

51 #更改文件名

52 for k infq_list:53 for v infx_list:54 os.rename(fdir + v,fdir +k)55 #每当修完一个文件名应该更新一下这个列表

56 fx_list.remove(v)57 print('改完名后的结果为:')58 os.system('ls')

今天回来看看,决定用函数的方式来练习并实现,代码有了一些小的改进,上代码:

1 #!/usr/bin/env python3.4

2 #coding:utf-8

3 importre4 importos5 fdir = '/root/github/shell/python3/py-9/test/'

6 fdir_list =os.listdir(fdir)7 fdir_f_count =len(fdir_list)8 print('当前目录的文件为:\n%s' %fdir_list)9 defgetFileformat(f_pre,f_num,f_end):10 fileformat = f_pre + f_num +f_end11 returnfileformat12 file_list =[]13 defgetTruefile():14 for i in range(1,fdir_f_count + 1):15 if i < 10:16 f_format = getFileformat('spam','00' + str(i),'.txt')17 file_list.append(f_format)18 else:19 f_format = getFileformat('spam','0' + str(i),'.txt')20 file_list.append(f_format)21 returnfile_list22 truefilelist =getTruefile()23 print('正确的文件编号应该是:\n%s' %truefilelist)24 lostnumfilelist =[]25 defgetLostnumfile(fdirlist,truelist):26 for lf intruelist:27 if lf not infdirlist:28 lostnumfilelist.append(lf)29 returnlostnumfilelist30 lostnumfile =getLostnumfile(fdir_list,file_list)31 print('缺失的文件编号为:\n%s' %lostnumfile)32

33 renamelist =[]34 defgetrenamefile(fdirlist,func):35 for a infdirlist:36 if a not infunc:37 renamelist.append(a)38 returnrenamelist39 renamefilelist =getrenamefile(fdir_list,file_list)40 print('需要修改的文件是\n%s' %renamefilelist)41

42 defrenamefile(func1,func2):43 for b infunc1:44 for c infunc2:45 os.rename(fdir + c,fdir +b)46 func2.remove(c)47 rename =renamefile(lostnumfile,renamefilelist)48 os.chdir(fdir)49 print('修改后的结果为:')50 os.system('ls')

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值