我们在日常处理文件时,经常用到os模块,但是有的时候你会发现,像拷贝、删除、打包、压缩等文件操作,在os模块中没有对应的函数去操作,下面我们就来讲讲高级的 文件、文件夹、压缩包 处理模块:shutil
功能:把一个文件的内容拷贝到另外一个文件中,可以是部分文件内容。
|
1
2
3
|
with open("f_old",‘r‘,encoding="utf-8") as f1,\ open("f_new","w",encoding="utf-8") as f2: shutil.copyfileobj(f1,f2) #拷贝文件的内容 |
注:经过试验,目前试验不出可以拷贝部分文件内容,先忘记可以拷贝部分内容把。
功能:拷贝文件,但是不拷贝所有权限
|
1
2
|
shutil.copyfile("f_old","f_new") #同一目录下拷贝文件shutil.copyfile(r‘D:\PycharmProjects\pyhomework\day5\shutil_mode\shutil_mod\f_old‘,r‘d:\f_new‘) #通过绝对路径拷贝文件 |
功能:拷贝文件的文件权限
|
1
2
3
4
5
6
7
8
9
10
11
12
|
[root@whtest137 ~]# lltotal 8-rwxr-xr-x 1 root root 0 Apr 1 16:05 zhangqigao #有执行权限-rw-r--r-- 1 whtest whtest 0 Apr 1 16:06 zhangqigao_old #没有执行权限>>> import os,shutil>>> os.chdir("/root")#拷贝"zhangqigao_old"权限给"zhangqigao">>> shutil.copymode("zhangqigao_old","zhangqigao") [root@whtest137 ~]# lltotal 8-rw-r--r-- 1 root root 0 Apr 1 16:05 zhangqigao # 获得跟"zhangqigao_old"一样的文件权限-rw-r--r-- 1 whtest whtest 0 Apr 1 16:06 zhangqigao_old |
功能:拷贝文件的状态信息,如:mode bits, atime, mtime, flags
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
#两个文件的创建时间和用户权限都不同[root@jenkins_sh temp]# lltotal 0-rw-r--r-- 1 root root 0 Apr 1 17:31 zhangqigao-rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old#python操作>>> import os,shutil>>> os.chdir("/temp")#zhangqigao 这个文件状态>>> os.stat("zhangqigao")posix.stat_result(st_mode=33188, st_ino=76808194, st_dev=2053L, st_nlink=1,st_uid=0, st_gid=0, st_size=0, st_atime=1491039109, st_mtime=1491039109,st_ctime=1491039109)#zhangqigao_old的文件状态>>> os.stat("zhangqigao_old")posix.stat_result(st_mode=33261, st_ino=76808195, st_dev=2053L, st_nlink=1,st_uid=101, st_gid=103, st_size=0, st_atime=1491035188, st_mtime=1491035188,st_ctime=1491035242)#拷贝zhangqigao_old 文件状态给zhangqigao 文件>>> shutil.copystat("zhangqigao_old","zhangqigao")# 拷贝后,zhangqigao文件的文件状态>>> os.stat("zhangqigao")posix.stat_result(st_mode=33261, st_ino=76808194, st_dev=2053L, st_nlink=1,st_uid=0, st_gid=0, st_size=0, st_atime=1491035188, st_mtime=1491035188,st_ctime=1491039237)#操作后两个文件比较[root@jenkins_sh temp]# lltotal 0-rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao #状态包括文件权限,文件创建的时间等,不包括文件所属用户和用户组-rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old |
功能:拷贝文件和文件的权限
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#拷贝前[root@jenkins_sh temp]# lltotal 0-rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old#拷贝中>>> import os,shutil>>> os.chdir("/temp")>>> shutil.copy("zhangqigao_old","zhangqigao")#拷贝结果输出[root@jenkins_sh temp]# lltotal 0-rwxr-xr-x 1 root root 0 Apr 1 17:42 zhangqigao #拷贝了zhangqigao_old文件和文件权限-rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old |
功能:拷贝文件和文件的状态
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
#拷贝前[root@jenkins_sh temp]# lltotal 0-rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old#拷贝中>>> import os,shutil>>> os.chdir("/temp")>>> shutil.copy2("zhangqigao_old","zhangqigao")#拷贝后[root@jenkins_sh temp]# lltotal 0-rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao #拷贝了zhangqigao_old的文件和状态-rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old |
功能:递归的去拷贝文件,相当于cp -r
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#操作前[root@jenkins_sh temp]# lltotal 4drwxr-xr-x 2 root root 4096 Apr 1 17:53 xiaogao[root@jenkins_sh temp]# cd xiaogao/;lltotal 0-rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao-rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old#操作中>>> import os,shutil>>> os.chdir("/temp")>>> shutil.copytree("xiaogao","gaogao") #递归拷贝#操作结果[root@jenkins_sh temp]# lltotal 8drwxr-xr-x 2 root root 4096 Apr 1 17:53 gaogao #拷贝成功drwxr-xr-x 2 root root 4096 Apr 1 17:53 xiaogao[root@jenkins_sh temp]# cd gaogao/;lltotal 0-rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao-rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao_old |
功能:递归的去删除文件,相当于:rm -fr
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#操作前[root@jenkins_sh temp]# lltotal 4drwxr-xr-x 2 root root 4096 Apr 1 17:53 xiaogao[root@jenkins_sh temp]# cd xiaogao/;lltotal 0-rwxr-xr-x 1 root root 0 Apr 1 16:26 zhangqigao-rwxr-xr-x 1 jenkins jenkins 0 Apr 1 16:26 zhangqigao_old#操作中>>> import os,shutil>>> os.chdir("/temp")>>> shutil.rmtree("xiaogao")#操作结果[root@jenkins_sh temp]# lltotal 0 #成功删除xiaogao目录 |
功能:递归的去移动文件 相当于:mv
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#操作前[root@jenkins_sh temp]# lltotal 4drwxr-xr-x 2 root root 4096 Apr 1 18:07 xiaogao-rw-r--r-- 1 root root 0 Apr 1 18:07 zhangqigao#操作中>>> import shutil>>> shutil.move("/temp/zhangqigao","/temp/xiaogao") #把文件移到目录中#操作结果[root@jenkins_sh xiaogao]# lltotal 4drwxr-xr-x 2 root root 4096 Apr 1 18:08 xiaogao[root@jenkins_sh temp]# cd xiaogao/;lltotal 0-rw-r--r-- 1 root root 0 Apr 1 18:07 zhangqigao |
功能:创建压缩包并且返回文件路径,例如:zip,tar
|
1
|
|
|
1
2
3
4
5
6
7
8
|
#指定路径>>> import shutil#把/temp下的xiaogao文件以zip压缩格式压缩,并且存放在/temp/zhangqigao目录下,"/temp/zhangqigao/xiaogao" 中的xiaogao是压缩名>>> shutil.make_archive("/temp/zhangqigao/xiaogao",‘zip‘,"/temp/xiaogao") ‘/temp/zhangqigao/xiaogao.zip‘ #压缩结果#默认当前路径>>> shutil.make_archive("xiaogao",‘zip‘,"/temp/xiaogao") ‘/temp/xiaogao.zip‘ |
功能:以zip的形式压缩文件,注意了这个只能压缩文件,不能压缩目录,如果压缩,也只能显示空目录。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
import zipfile# 压缩z = zipfile.ZipFile(‘laxi.zip‘, ‘w‘)z.write(‘a.log‘) #写入z.write(‘data.data‘)z.close() #关闭# 解压z = zipfile.ZipFile(‘laxi.zip‘, ‘r‘)z.extractall() #解压z.close() |
功能:以tar的形式打包文件,这边能打包所以文件,包括目录
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
import tarfile# 打包tar = tarfile.open(‘your.tar‘,‘w‘)#不加arcname打的是绝对路径,也就是/Users/wupeiqi/PycharmProjects/bbs2.zip,加这个表示你在your.tar中加什么文件就写什么文件名,也就是bbs2.ziptar.add(‘/Users/wupeiqi/PycharmProjects/bbs2.zip‘, arcname=‘bbs2.zip‘)tar.add(‘/Users/wupeiqi/PycharmProjects/cmdb.zip‘, arcname=‘cmdb.zip‘)tar.close()# 解压tar = tarfile.open(‘your.tar‘,‘r‘)tar.extractall() # 可设置解压地址tar.close() |
之前我们说不管是json也好,还是pickle也好,在python3中只能dump一次和load一次,不能dump多次,和load多次,但是我们真想要dump多次和load多次怎么办呢,并且能事项数据的持久化呐?好吧,今天我们就来说说这个shelve模块。
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import shelve #导入shelve模块def stu_data(name,age): #定义一个函数 print("register stu:",name,age)name = ["test","zhang","qi","gao"] #定义一个列表info = { "name":"zhangqigao","age":18} #定义一个字典with shelve.open("shelve_test") as d: d["test"] = name #持久化列表 d["info"] = info #持久化字典 d["func"] = stu_data #持久化函数 |
代码执行结果:
生成三个文件夹,分别是:shelve_test.dir、shelve_test.dat、shelve_test.bak
①shelve_test.dir内容
|
1
2
3
|
‘test‘, (0, 50)‘func‘, (1024, 24)‘info‘, (512, 48) |
②shelve_test.dat内容
|
1
2
3
4
5
6
|
?]q (X testqX zhangqX qiqX gaoqe.?}q (X nameqX zhangqigaoqX ageqKu.?c__main__stu_dataq . |
③shelve_test.bak内容
|
1
2
3
|
‘test‘, (0, 50)‘func‘, (1024, 24)‘info‘, (512, 48) |
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
import shelvedef stu_data(name,age): #这边一定要定义相同名字的函数,不然执行报错 print("stu:",name,age)with shelve.open("shelve_test") as f: print(f[‘test‘]) #解析列表 print(f[‘info‘]) #解析字典 print(f["func"]("zhangqsan",22)) #解析函数#输出[‘test‘, ‘zhang‘, ‘qi‘, ‘gao‘]{‘age‘: 18, ‘name‘: ‘zhangqigao‘}stu: zhangqsan 22None |
|
1
2
3
4
5
6
7
8
9
10
11
12
|
>>> import shelve>>> d = shelve.open("shelve_test")>>> dir(d)[‘_MutableMapping__marker‘, ‘__abstractmethods__‘, ‘__class__‘, ‘__contains__‘, ‘__del__‘, ‘__delattr__‘, ‘__delitem__‘, ‘__dict__‘, ‘__dir__‘, ‘__doc__‘, ‘__enter__‘, ‘__eq__‘, ‘__exit__‘, ‘__format__‘, ‘__ge__‘, ‘__getattribute__‘, ‘__getitem__‘, ‘__gt__‘, ‘__hash__‘, ‘__init__‘,‘__iter__‘, ‘__le__‘, ‘__len__‘, ‘__lt__‘, ‘__module__‘, ‘__ne__‘, ‘__new__‘, ‘__reduce__‘, ‘__reduce_ex__‘, ‘__repr__‘, ‘__setattr__‘, ‘__setitem__‘, ‘__sizeof__‘, ‘__slots__‘, ‘__str__‘, ‘__subclasshook__‘, ‘__weakref__‘, ‘_abc_cache‘, ‘_abc_negative_cache‘,‘_abc_negative_cache_version‘, ‘_abc_registry‘, ‘_protocol‘, ‘cache‘, ‘clear‘, ‘close‘, ‘dict‘, ‘get‘, ‘items‘, ‘keyencoding‘, ‘keys‘, ‘pop‘, ‘popitem‘, ‘setdefault‘, ‘sync‘, ‘update‘,‘values‘, ‘writeback‘] |
说明:update方法是如果序列化的值存在,则更新,如果不存在,则新增,用法:update({key:序列化对象})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
#dumps到文件中import shelveinfo = { "name":"zhangqigao", "age":18}with shelve.open("shelve_test") as d: d[‘qigaotest‘] = info #变量存在 d.update({‘qigaotest‘:"shuaigaogao"}) #更新已经key为"qigaotest"的值#loads到内存中import shelvewith shelve.open("shelve_test") as f: print(f.get("qigaotest"))#输出shuaigaogao |
说明:把文件中的值load到内存中时,通过get它的key值获取
|
1
2
3
4
5
6
7
|
import shelvewith shelve.open("shelve_test") as f: print(f.get("qigaotest")) #或者是f["qigaotest"]#输出shuaigaogao |
注意:如果是通过f["qigaotest"]这种方法取,如果值不存在则会报错,通过get去取,不存在,则会返回none
xml是实现不同语言或者程序之间进行数据交换的协议,跟json差不多,但是json使用起来更简单,不过,古时候,在json还没有诞生的黑暗年代,大家只能选择xml,到现在仍然有很多传统的公司,像金融行业的很多系统的接口还是xml。
说明:就是通过<>节点来区别数据结构的,格式如下:
<?xml version="1.0"?>
<data>
<country name="Liechtenstein">
<rank updated="yes">2</rank>
<year>2008</year>
<gdppc>141100</gdppc>
<neighbor name="Austria" direction="E"/>
<neighbor name="Switzerland" direction="W"/>
</country>
<country name="Singapore">
<rank updated="yes">5</rank>
<year>2011</year>
<gdppc>59900</gdppc>
<neighbor name="Malaysia" direction="N"/>
</country>
<country name="Panama">
<rank updated="yes">69</rank>
<year>2011</year>
<gdppc>13600</gdppc>
<neighbor name="Costa Rica" direction="W"/>
<neighbor name="Colombia" direction="E"/>
</country>
</data>
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import xml.etree.ElementTree as ettree = et.parse("xmltest.xml")root = tree.getroot() #获取根节点print(root.tag) #打印节点名称#遍历xml文档for child in root: print(child.tag,child.attrib) #分别打印子节点名称和子节点属性 #遍历子节点下的所有节点 for i in child: print(i.tag,i.text) #打印子节点下节点的节点名和节点值 #只遍历year节点 for i in child.iter("year"): print("\t",i.tag,i.attrib,i.text)#只遍历year节点for node in root.iter("year"): print(node.tag,node.text) #打印year的节点名和节点值 |
注:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
|
import xml.etree.ElementTree as ettree = et.parse("xmltest.xml")root = tree.getroot()#修改year节点的值for node in root.iter("year"): new_year = int(node.text) + 1 #修改节点值 node.text = str(new_year) #修改后强制转换成字符串类型 node.tag = "myyear" #修改节点名 node.set("zhangqigao",‘handsome‘) #修改节点属性tree.write("xmltest1.xml") #修改完成后,重新写入xml文件(可以是任何文件,包括原来的) |
注:可以修改xml文件中的任何内容,包括本身的节点名,修改后一定要有写入xml文件的操作。
|
1
2
3
4
5
6
7
8
9
10
11
12
|
import xml.etree.ElementTree as ettree = et.parse("xmltest.xml")root = tree.getroot()#删除for country in root.findall("country"): #找到第一层子节点 rank = int(country.find("rank").text) #找到子节点下的‘rank‘节点的节点值 if rank > 50: root.remove(country) #删除子节点tree.write("xmltest1.xml") #重新写入xml文件 |
注:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
import xml.etree.ElementTree as etnew_xml = et.Element("namelist") #创建根节点#创建第一层子节点,后面参数依次是:父节点,子节点,子节点属性name = et.SubElement(new_xml,"name",attrib={"zhangqigao":"handsome"})#创建第二层子节点age = et.SubElement(name,"age",attrib={"check":"yes"})#设置第二层节点值age.text = ‘22‘sex = et.SubElement(name,"sex")sex.text = "man"#创建另外一个第一层子节点name2 = et.SubElement(new_xml,"name",attrib={"zhangqigao":"haoshuai"})#创建其第二层子节点age = et.SubElement(name2,"age")age.text = ‘19‘ET = et.ElementTree(new_xml) #生成新的xml文档ET.write("test.xml",encoding="utf-8",xml_declaration=True) #在新xml文件的开头自动添加:<?xml version=‘1.0‘ encoding=‘utf-8‘?>et.dump(new_xml) #在屏幕上打印生成的格式 |
注:et.dump(new_xml)这个有什么作用呢?当你需要直接把字符串传过去,不需要串文件时,用这个就ok了。
在很多情况下,我们都需要修改配置文件,但是,有些配置文件,如mysql数据库的配置文件怎么修改呢?我们今天就来写一下,用于生产和修改常见配置文件的模块:configparser。
[DEFALUT] compressionlevel = 9 serveraliveinterval = 45 compression = yes forwardx11 = yes [bitbucket.org] user = hg [topsecret.server.com] host port = 50022 forwardx11 = no
说明:其实有的时候我们很少创建,除非是用系统管理,一般直接修改就可以了,但是还是要掌握的。
代码如下:
import configparser #导入configparser模块
#创建一个对象
config = configparser.ConfigParser()
#配置默认全局配置组
config["DEFALUT"] = {"ServerAliveInterval":"45",
"Compression":"yes",
"CompressionLevel":"9"
}
#配置第一个其他组
config["bitbucket.org"] = {}
#没有没有赋给一个变量,直接赋值
config["bitbucket.org"]["User"] = ‘hg‘
#配置第二个其他组
config["topsecret.server.com"] = {}
#这边就赋给一个变量
topsecret = config["topsecret.server.com"]
#通过变量赋值
topsecret["Host Port"] = ‘50022‘
topsecret["ForwardX11"] = ‘no‘
#给全局配置组赋值
config["DEFALUT"]["ForwardX11"] = "yes"
#操作完毕,把配置的内容写入一个配置文件中
with open("example.ini","w") as configfile:
config.write(configfile)
>>> import configparser
>>> config = configparser.ConfigParser()
>>> config.sections() #不读取配置文件,组名列表为空
[]
>>> config.read("example.ini") #读取配置文件,返回配置文件名
[‘example.ini‘]
>>> config.sections() #返回除默认配置组的其他组名
[‘bitbucket.org‘, ‘topsecret.server.com‘]
>>> config.defaults() #读取默认配置组,并返回有序字典
OrderedDict([(‘compressionlevel‘, ‘9‘), (‘serveraliveinterval‘, ‘45‘), (‘compression‘, ‘yes‘), (‘forwardx11‘, ‘yes‘)])
>>> ‘bitbucket.org‘ in config #组名存在 True >>> ‘zhangqigao.org‘ in config #组名不存在 False
>>> config["bitbucket.org"]["User"] #读取"bitbucket.org"配置组中的值 ‘hg‘ >>> config["DEFAULT"]["Compression"] #读取默认配置组中的值 ‘yes‘ >>> topsecret = config[‘topsecret.server.com‘] #把配置组赋给一个对象 >>> topsecret[‘ForwardX11‘] #通过对象获取值 ‘no
>>> for key in config["bitbucket.org"]: #循环打印bitbucket.org组下的key值 ... print(key) ... #输出,只打印默认组和bitbucket.org组的key值 user compressionlevel serveraliveinterval compression forwardx11 >>> for key in config["topsecret.server.com"]:#循环打印topsecret.server.com组下的key值 ... print(key) ... #输出,只打印默认组和topsecret.server.com组的key值 host port forwardx11 compressionlevel serveraliveinterval compression
注:默认组是全局的,所以循环遍历key值时,会遍历从默认组和需要遍历的组一起遍历出来。
[DEFAULT] k1 = v1 k2 = v2 [section1] k3 = v3 k4:v4 [section2] k5 = 5
import configparser
config = configparser.ConfigParser()
config.read("i.cfg")
sec = config.sections()
print(sec)
#输出
[‘section1‘, ‘section2‘]
options = config.options("section2") #返回默认组和section2组的key值
print(options)
#输出
[‘k5‘, ‘k1‘, ‘k2‘]
item_list = config.items("section2") #返回默认组和section2组的key-value值
print(item_list)
#输出
[(‘k1‘, ‘v1‘), (‘k2‘, ‘v2‘), (‘k5‘, ‘5‘)]
val1 = config.get("section2","k1") #获取section2组中k1对应的值,是否可取是按照上面返回的列表
print(val1)
#输出
v1
val2 = config.getint("section2","k5") #返回section2中k5的值,这个值返回的int类型的
print(val2)
#输出
5
①删除section和option
import configparser
config = configparser.ConfigParser()
config.read("i.cfg")
config.remove_option("section1","k3") #删除section1组下的k3
config.remove_section("section2") #删除section2组
with open("i.cfg2","w") as f: #重新写入一个文件
config.write(f)
#输出,写入文件的内容
[DEFAULT]
k1 = v1
k2 = v2
[section1]
k4 = v4
②添加section
import configparser
config = configparser.ConfigParser()
config.read("i.cfg")
sec = config.has_option("section2","k5") #是否存在section2组内有k5
print(sec)
#输出
True
sec = config.has_section("zhangqigao") #是否存在zhangqigao组
print(sec)
#输出
False
config.add_section("zhangqigao") #添加section组zhangqigao
config.add_section("zhangqigao") #重新写入到一个配置文件中
with open("i.cfg3","w") as f:
config.write(f)
③添加或者设置option
import configparser
config = configparser.ConfigParser()
config.read("i.cfg")
config.set("zhangqigao","z","18") #设置或者添加zhangqigao中option值
with open("i.cfg3","w") as f: #重新写入文件中
config.write(f)
Python函数和常用模块【day06】:shutil-shelve-xml-configparser模块
原文:http://www.cnblogs.com/luoahong/p/7195983.html