标签:支持 路径 ict 数据结构 example 父节点 sizeof bucket weakref
我们在日常处理文件时,经常用到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 ~] # ll total 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 ~] # ll total 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] # ll total 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] # ll total 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] # ll total 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] # ll total 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] # ll total 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] # ll total 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] # ll total 4 drwxr - xr - x 2 root root 4096 Apr 1 17 : 53 xiaogao [root@jenkins_sh temp] # cd xiaogao/;ll total 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] # ll total 8 drwxr - 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/;ll total 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] # ll total 4 drwxr - xr - x 2 root root 4096 Apr 1 17 : 53 xiaogao [root@jenkins_sh temp] # cd xiaogao/;ll total 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] # ll total 0 #成功删除xiaogao目录 |
功能:递归的去移动文件 相当于:mv
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
#操作前 [root@jenkins_sh temp] # ll total 4 drwxr - 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] # ll total 4 drwxr - xr - x 2 root root 4096 Apr 1 18 : 08 xiaogao [root@jenkins_sh temp] # cd xiaogao/;ll total 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.zip tar.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_data q . |
③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 shelve def 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 22 None |
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 shelve info = { "name" : "zhangqigao" , "age" : 18 } with shelve. open ( "shelve_test" ) as d: d[ ‘qigaotest‘ ] = info #变量存在 d.update({ ‘qigaotest‘ : "shuaigaogao" }) #更新已经key为"qigaotest"的值 #loads到内存中 import shelve with shelve. open ( "shelve_test" ) as f: print (f.get( "qigaotest" )) #输出 shuaigaogao |
说明:把文件中的值load到内存中时,通过get它的key值获取
1
2
3
4
5
6
7
|
import shelve with 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 et tree = 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 et tree = 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 et tree = 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 et new_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模块
标签:支持 路径 ict 数据结构 example 父节点 sizeof bucket weakref
原文地址:http://www.cnblogs.com/luoahong/p/7195983.html