常用模块之 shutil,json,pickle,shelve,xml,configparser
shutil
高级的文件、文件夹、压缩包 处理模块
- shutil.copyfileobj(fsrc, fdst[, length]) 将文件内容拷贝到另一个文件中
- import shutil
- shutil.copyfileobj(open('old.xml','r'), open('new.xml', 'w'))
- shutil.copyfile(src, dst) 拷贝文件
- shutil.copyfile('f1.log', 'f2.log') #目标文件无需存在
- shutil.copymode(src, dst) 仅拷贝权限。内容、组、用户均不变
- shutil.copymode('f1.log', 'f2.log') #目标文件必须存在
- shutil.copystat(src, dst) 仅拷贝状态的信息,包括:mode bits, atime, mtime, flags
- shutil.copystat('f1.log', 'f2.log') #目标文件必须存在
- shutil.copy(src, dst) 拷贝文件和权限
- import shutil
- shutil.copy('f1.log', 'f2.log')
- shutil.copy2(src, dst) 拷贝文件和状态信息
- import shutil
- shutil.copy2('f1.log', 'f2.log')
- shutil.ignore_patterns(*patterns)
- shutil.copytree(src, dst, symlinks=False, ignore=None)
- 递归的去拷贝文件夹
- import shutil
- shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目标目录不能存在,注意对folder2目录父级目录要有可写权限,ignore的意思是排除
- import shutil
- shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
- '''
- 通常的拷贝都把软连接拷贝成硬链接,即对待软连接来说,创建新的文件
- '''
- shutil.rmtree(path[, ignore_errors[, onerror]])
- 递归的去删除文件
- import shutil
- shutil.rmtree('folder1')
- shutil.move(src, dst)
- 递归的去移动文件,它类似mv命令,其实就是重命名。
- shutil.move('folder1', 'folder3')
- shutil.make_archive(base_name, format,...)
- 创建压缩包并返回文件路径,例如:zip、tar
- 创建压缩包并返回文件路径,例如:zip、tar
- base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
- 如 data_bak =>保存至当前路径
- 如:/tmp/data_bak =>保存至/tmp/
- format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
- root_dir: 要压缩的文件夹路径(默认当前目录)
- owner: 用户,默认当前用户
- group: 组,默认当前组
- logger: 用于记录日志,通常是logging.Logger对象
- 将 /data 下的文件打包放置当前程序目录
- import shutil
- ret = shutil.make_archive("data_bak", 'gztar', root_dir='/data')
- 将 /data下的文件打包放置 /tmp/目录
- import shutil
- ret = shutil.make_archive("/tmp/data_bak", 'gztar', root_dir='/data')
- 用shutil直接解压
- shutil.unpack_archive("1111.zip")
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的
- import zipfile
- #压缩
- z=zipfile.ZipFile('laxi.zip','w') #在当前目录下建立一个名为laxi的空压缩包(已经存在的话就以写入模式打开)
- z.write('uesr_data.json') #讲一个名为uesr_data.json的文件写入压缩包中
- z.close()
- #解压
- z=zipfile.ZipFile("laxi.zip","r")
- z.extractall(path=".") #解压路径为当前路径
- z.close()
zipfile压缩解压
- import tarfile
- # 压缩
- t=tarfile.open(r'F:\代码练习\uesr_data.json','w')
- t.add('/test1/a.py',arcname='a.bak') #arcname指定存档文件中文件的替代名称。
- t.add('/test1/b.py',arcname='b.bak')
- t.close()
- #解压
- t=tarfile.open('/tmp/egon.tar','r')
- t.extractall('/egon')
- t.close()
tarfile压缩解压
json与pickle
什么叫序列化——将原本的字典、列表等内容转换成一个字符串的过程就叫做序列化
为什么不用eval反序列化
- 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过,eval方法是有局限性的,对于普通的数据类型,json.loads和eval都能用,但遇到特殊类型的时候,eval就不管用了,所以eval的重点还是通常用来执行一个字符串表达式,并返回表达式的值,
- eval()函数十分强大,但是eval是做什么的?eval官方demo解释为:将字符串str当成有效的表达式来求值并返回计算结果。强大的函数有代价。安全性是其最大的缺点。
- 想象一下,如果我们从文件中读出的不是一个数据结构,而是一句"删除文件"类似的破坏性语句,那么后果实在不堪设设想。
- 而使用eval就要担这个风险。
- 所以,我们并不推荐用eval方法来进行反序列化操作(将str转换成python中的数据结构)
序列化的目的
- 1,持久保存状态
- 2,跨平台数据交互
json
如果我们要在不同的编程语言之间传递对象,就必须把对象序列化为标准格式,比如XML,但更好的方法是序列化为JSON,因为JSON表示出来就是一个字符串,可以被所有语言读取,也可以方便地存储到磁盘或者通过网络传输。JSON不仅是标准格式,并且比XML更快,而且可以直接在Web页面中读取,非常方便。
JSON表示的对象就是标准的JavaScript语言的对象,JSON和Python内置的数据类型对应如下:
- js 中的数据类型 python数据类型 的对应关系
- {} 字典
- [] list
- string "" str python里面单引号和双引号都可以,js里面只能是双引号
- int/float int/float
- true/false True/False
- null None
json格式的语法规范:
最外层通常是一个字典或列表
{} or []
只要你想写一个json格式的数据 那么最外层直接写{}
字符串必须是双引号
你可以在里面套任意多的层次
json模块的核心功能 dump dumps load loads 不带s封装write 和 read,但须要一个文件句柄
- import json
- dic = {'k1':'v1','k2':'v2','k3':'v3'}
- str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串
- print(type(str_dic),str_dic) #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"}
- #注意,json转换完的字符串类型的字典中的字符串是由""表示的
- dic2 = json.loads(str_dic) #反序列化:将一个字符串格式的字典转换成一个字典
- #注意,要用json的loads功能处理的字符串类型的字典中的字符串必须由""表示
- print(type(dic2),dic2) #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'}
- list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}]
- str_dic = json.dumps(list_dic) #也可以处理嵌套的数据类型
- print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}]
- list_dic2 = json.loads(str_dic)
- print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]
loads与dumps
- import json
- f = open('json_file','w')
- dic = {'k1':'v1','k2':'v2','k3':'v3'}
- json.dump(dic,f) #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件
- f.close()
- f = open('json_file')
- dic2 = json.load(f) #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回
- f.close()
- print(type(dic2),dic2)
load与dump
- import json
- f = open('file','w')
- json.dump({'国籍':'中国'},f)
- ret = json.dumps({'国籍':'中国'})
- f.write(ret+'\n')
- json.dump({'国籍':'美国'},f,ensure_ascii=False)
- ret = json.dumps({'国籍':'美国'},ensure_ascii=False)
- f.write(ret+'\n')
- f.close()
ensure_ascii关键字参数
- Serialize obj to a JSON formatted str.(字符串表示的json对象)
- Skipkeys:默认值是False,如果dict的keys内的数据不是python的基本类型(str,unicode,int,long,float,bool,None),设置为False时,就会报TypeError的错误。此时设置成True,则会跳过这类key
- ensure_ascii:,当它为True的时候,所有非ASCII码字符显示为\uXXXX序列,只需在dump时将ensure_ascii设置为False即可,此时存入json的中文即可正常显示。)
- If check_circular is false, then the circular reference check for container types will be skipped and a circular reference will result in an OverflowError (or worse).
- If allow_nan is false, then it will be a ValueError to serialize out of range float values (nan, inf, -inf) in strict compliance of the JSON specification, instead of using the JavaScript equivalents (NaN, Infinity, -Infinity).
- indent:应该是一个非负的整型,如果是0就是顶格分行显示,如果为空就是一行最紧凑显示,否则会换行且按照indent的数值显示前面的空白分行显示,这样打印出来的json数据也叫pretty-printed json
- separators:分隔符,实际上是(item_separator, dict_separator)的一个元组,默认的就是(‘,’,’:’);这表示dictionary内keys之间用“,”隔开,而KEY和value之间用“:”隔开。
- default(obj) is a function that should return a serializable version of obj or raise TypeError. The default simply raises TypeError.
- sort_keys:将数据根据keys的值进行排序。
- To use a custom JSONEncoder subclass (e.g. one that overrides the .default() method to serialize additional types), specify it with the cls kwarg; otherwise JSONEncoder is used.
其他参数说明
- import json
- data = {'username':['李华','二愣子'],'sex':'male','age':16}
- json_dic2 = json.dumps(data,sort_keys=True,indent=2,separators=(',',':'),ensure_ascii=False)
- print(json_dic2)
json格式化输出
pickle
pickle模块主要功能 dump load dumps loads
dump是序列化 load反序列化
不带s的是帮你封装write read 更方便
load函数可以多次执行 每次load 都是往后在读一个对象 如果没有了就抛出异常Ran out of input
- import pickle
- # 用户注册后得到的数据
- name = "高跟"
- password = ""
- height = 1.5
- hobby = ["吃","喝","赌","飘",{1,2,3}]
- with open("userdb.txt","wt",encoding="utf-8") as f:
- text = "|".join([name,password,str(height)])
- f.write(text)
- pickle支持python中所有的数据类型
- user = {"name":name,"password":password,"height":height,"hobby":hobby,"test":3}
- 序列化的过程
- with open("userdb.pkl","ab") as f:
- userbytes = pickle.dumps(user)
- f.write(userbytes)
- 反序列化过程
- with open("userdb.pkl","rb") as f:
- userbytes = f.read()
- user = pickle.loads(userbytes)
- print(user)
- print(type(user))
- dump 直接序列化到文件
- with open("userdb.pkl","ab") as f:
- pickle.dump(user,f)
- load 从文件反序列化
- with open("userdb.pkl","rb") as f:
- user = pickle.load(f)
- print(user)
- print(pickle.load(f))
- print(pickle.load(f))
- print(pickle.load(f))
pickle
如果我们将一个字典或者序列化成了一个json存在文件里,那么java代码或者js代码也可以拿来用,但是如果我们用pickle进行序列化,其他语言就不能读
shelve
也用于序列化,它与pickle的不同之处在于 ,不需要关心文件模式什么的 类似把它当成一个字典来看待,它可以直接对数据进行修改 而不用覆盖原来的数据,而pickle 你想要修改只能 用wb模式来覆盖
- import shelve
- user = {"name":"高根"}
- s = shelve.open("userdb.shv")
- s["user"] = user
- s.close()
- s = shelve.open("userdb.shv",writeback=True)
- print(s["user"])
- s["user"]["age"] = 20
- s.close()
xml
xml是实现不同语言或程序之间进行数据交换的协议,跟json差不多,但json使用起来更简单,不过在json还没诞生前,大家只能选择用xml呀,至今很多传统公司如金融行业的很多系统的接口还主要是xml。
- import xml.etree.ElementTree as ElementTree (这个另起一个名字随意,看着舒服就行)
- 解析d.xml
- tree = ElementTree.parse("d.xml")
- print(tree)
- 获取根标签
- rootTree = tree.getroot()
- 三种获取标签的方式
- 获取所有人的年龄 iter是用于在全文范围获取标签
- for item in rootTree.iter("age"):
- # 一个标签三个组成部分
- print(item.tag) # 标签名称
- print(item.attrib) # 标签的属性
- print(item.text) # 文本内容
- 第二种 从当前标签的子标签中找到一个名称为age的标签 如果有多个 找到的是第一个
- print(rootTree.find("age").attrib)
- 第三种 从当前标签的子标签中找到所有名称为age的标签
- print(rootTree.findall("age"))
- 获取单个属性
- stu = rootTree.find("stu")
- print(stu.get("age"))
- print(stu.get("name"))
- 删除子标签
- rootTree.remove(stu)
- 添加子标签
- 要先创建一个子标签
- newTag = ElementTree.Element("这是新标签",{"一个属性":"值"})
- rootTree.append(newTag)
- 另外,节点还有set(设置节点属性)
- 写入文件
- tree.write("f.xml",encoding="utf-8")
- import xml.etree.ElementTree as ET
- new_xml = ET.Element("namelist")
- name = ET.SubElement(new_xml,"name",attrib={"enrolled":"yes"})
- age = ET.SubElement(name,"age",attrib={"checked":"no"})
- sex = ET.SubElement(name,"sex")
- sex.text = ''
- name2 = ET.SubElement(new_xml,"name",attrib={"enrolled":"no"})
- age = ET.SubElement(name2,"age")
- age.text = ''
- et = ET.ElementTree(new_xml) #生成文档对象
- et.write("test.xml", encoding="utf-8",xml_declaration=True)
- ET.dump(new_xml) #打印生成的格式
自己创建xml文档
- ElementTree生来就是为了处理XML,它在Python标准库中有两种实现:一种是纯Python实现的,如xml.etree.ElementTree,另一种是速度快一点的xml.etree.cElementTree。注意:尽量使用C语言实现的那种,因为它速度更快,而且消耗的内存更少。
- a. 遍历根节点的下一层
- b. 下标访问各个标签、属性、文本
- c. 查找root下的指定标签
- d. 遍历XML文件
- e. 修改XML文件
- #coding=utf-8
- #通过解析xml文件
- '''
- try:
- import xml.etree.CElementTree as ET
- except:
- import xml.etree.ElementTree as ET
- 从Python3.3开始ElementTree模块会自动寻找可用的C库来加快速度
- '''
- import xml.etree.ElementTree as ET
- import os
- import sys
- '''
- XML文件读取
- <?xml version="1.0" encoding="utf-8"?>
- <catalog>
- <maxid>4</maxid>
- <login username="pytest" passwd='123456'>dasdas
- <caption>Python</caption>
- <item id="4">
- <caption>测试</caption>
- </item>
- </login>
- <item id="2">
- <caption>Zope</caption>
- </item>
- </catalog>
- '''
- #遍历xml文件
- def traverseXml(element):
- #print (len(element))
- if len(element)>0:
- for child in element:
- print (child.tag, "----", child.attrib)
- traverseXml(child)
- #else:
- #print (element.tag, "----", element.attrib)
- if __name__ == "__main__":
- xmlFilePath = os.path.abspath("test.xml")
- print(xmlFilePath)
- try:
- tree = ET.parse(xmlFilePath)
- print ("tree type:", type(tree))
- # 获得根节点
- root = tree.getroot()
- except Exception as e: #捕获除与程序退出sys.exit()相关之外的所有异常
- print ("parse test.xml fail!")
- sys.exit()
- print ("root type:", type(root))
- print (root.tag, "----", root.attrib)
- #遍历root的下一层
- for child in root:
- print ("遍历root的下一层", child.tag, "----", child.attrib)
- #使用下标访问
- print (root[0].text)
- print (root[1][1][0].text)
- print (20 * "*")
- #遍历xml文件
- traverseXml(root)
- print (20 * "*")
- #根据标签名查找root下的所有标签
- captionList = root.findall("item") #在当前指定目录下遍历
- print (len(captionList))
- for caption in captionList:
- print (caption.tag, "----", caption.attrib, "----", caption.text)
- #修改xml文件,将passwd修改为999999
- login = root.find("login")
- passwdValue = login.get("passwd")
- print ("not modify passwd:", passwdValue)
- login.set("passwd", "") #修改,若修改text则表示为login.text
- print ("modify passwd:", login.get("passwd"))
处理xml文件
configparser
该模块适用于配置文件的格式与windows ini文件类似,可以包含一个或多个节(section),每个节可以有多个参数(键=值)。
- [db]
- db_port = 3306
- db_user = root
- db_host = 127.0.0.1
- db_pass = xgmtest
- [concurrent]
- processor = 20
- thread = 10
- import configparser
- config=configparser.ConfigParser()
- config.read('a.cfg')
- #查看所有的标题
- res=config.sections() #['section1', 'section2']
- print(res)
- #查看标题section1下所有key=value的key
- options=config.options('section1')
- print(options) #['k1', 'k2', 'user', 'age', 'is_admin', 'salary']
- #查看标题section1下所有key=value的(key,value)格式
- item_list=config.items('section1')
- print(item_list) #[('k1', 'v1'), ('k2', 'v2'), ('user', 'egon'), ('age', '18'), ('is_admin', 'true'), ('salary', '31')]
- #查看标题section1下user的值=>字符串格式
- val=config.get('section1','user')
- print(val) #egon
- #查看标题section1下age的值=>整数格式
- val1=config.getint('section1','age')
- print(val1) #
- #查看标题section1下is_admin的值=>布尔值格式
- val2=config.getboolean('section1','is_admin')
- print(val2) #True
读取
- import configparser
- config=configparser.ConfigParser()
- config.read('a.cfg',encoding='utf-8')
- 删除整个标题section2
- config.remove_section('section2')
- 删除标题section1下的某个k1和k2
- config.remove_option('section1','k1')
- config.remove_option('section1','k2')
- 判断是否存在某个标题
- print(config.has_section('section1'))
- 判断标题section1下是否有user
- print(config.has_option('section1',''))
- 添加一个标题
- config.add_section('egon')
- 在标题egon下添加name=egon,age=18的配置
- config.set('egon','name','egon')
- config.set('egon','age',18) #报错,必须是字符串
- 最后将修改的内容写入文件,完成最终的修改
- config.write(open('a.cfg','w'))
修改
常用模块之 shutil,json,pickle,shelve,xml,configparser的更多相关文章
- python笔记-7(shutil/json/pickle/shelve/xml/configparser/hashlib模块)
一.shutil模块--高级的文件.文件夹.压缩包处理模块 1.通过句柄复制内容 shutil.copyfileobj(f1,f2)对文件的复制(通过句柄fdst/fsrc复制文件内容) 源码: Le ...
- 常用模块(random,os,json,pickle,shelve)
常用模块(random,os,json,pickle,shelve) random import random print(random.random()) # 0-1之间的小数 print(rand ...
- 模块 - json/pickle/shelve/xml/configparser
序列化: 序列化是指把内存里的数据类型转变成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes. 为什么要序列化: 有种办法可以直接把内存数据(eg:10个列表,3 ...
- Python全栈之路----常用模块----序列化(json&pickle&shelve)模块详解
把内存数据转成字符,叫序列化:把字符转成内存数据类型,叫反序列化. Json模块 Json模块提供了四个功能:序列化:dumps.dump:反序列化:loads.load. import json d ...
- Python全栈开发记录_第八篇(模块收尾工作 json & pickle & shelve & xml)
由于上一篇篇幅较大,留下的这一点内容就想在这里说一下,顺便有个小练习给大家一起玩玩,首先来学习json 和 pickle. 之前我们学习过用eval内置方法可以将一个字符串转成python对象,不过, ...
- json/pickle/shelve/xml/configparser/hashlib/subprocess - 总结
序列化:序列化指把内存里的数据类型转成字符串,以使其能存储到硬盘或通过网络传输到远程,因为硬盘或网络传输时只能接受bytes为什么要序列化:可以直接把内存数据(eg:10个列表,3个嵌套字典)存到硬盘 ...
- 常用模块(json/pickle/shelve/XML)
一.json模块(重点) 一种跨平台的数据格式 也属于序列化的一种方式 介绍模块之前,三个问题: 序列化是什么? 我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化. 反序列化又是什么? 将 ...
- Python学习笔记——基础篇【第六周】——json & pickle & shelve & xml处理模块
json & pickle 模块(序列化) json和pickle都是序列化内存数据到文件 json和pickle的区别是: json是所有语言通用的,但是只能序列化最基本的数据类型(字符串. ...
- python 序列化及其相关模块(json,pickle,shelve,xml)详解
什么是序列化对象? 我们把对象(变量)从内存中编程可存储或传输的过程称之为序列化,在python中称为pickle,其他语言称之为serialization ,marshalling ,flatter ...
- python序列化及其相关模块(json,pickle,shelve,xml)详解
什么是序列化对象? 我们把对象(变量)从内存中编程可存储或传输的过程称之为序列化,在python中称为pickle,其他语言称之为serialization ,marshalling ,flatter ...
随机推荐
- 【aws】
云服务器EC2 动态调整云服务器ec2 cpu.内存大小: 在ec2实例上右键,Instance settings--> Change Instance Type 选择一个合适的type 云数据 ...
- Can you answer these queries?---hdu4027
题目链接 有n个数:当操作为1时求L到R的和: 当操作为0时更新L到R为原来的平方根: 不过如果仔细演算的话会发现一个2^64数的平方根开8次也就变成了 1,所以也更新不了多少次,所以可以每次更新到底 ...
- Java非静态内部类为什么不能有静态成员
我们可以把InnerClass看成OuterClass的非静态成员,它的初始化必须在外部类对象创建后以后进行,要加载InnerClass必须在实例化OuterClass之后完成 ,java虚拟机要求所 ...
- idong常用js总结
1.判断屏幕高度 $(document).ready(function() { $("#left").height($(window).height()); $(&qu ...
- openstack 部署笔记--基本环境准备
基础信息 配置:centos7.3 8G内存 4核处理器 单网卡 控制节点IP:192.168.15.243 计算节点IP:192.168.15.238 openstack 版本:ocata 配置信 ...
- [LeetCode] 301. Remove Invalid Parentheses_Hard tag:BFS
Remove the minimum number of invalid parentheses in order to make the input string valid. Return all ...
- webdriver模拟鼠标悬浮
未经作者允许,禁止转载! 有时候会遇到这样的情况,鼠标停留在某一区域,不需要点击,悬浮在这一区域的上方就会显示该区域的下拉框,如下图 下面将鼠标停留在“日历”和“星座”这两个部分之间来回悬浮,下面是代 ...
- Vue.Js添加自定义插件
基于上篇我们讲了 在window下搭建Vue.Js开发环境 我们可以开发自己的vue.js插件发布到npm上,供大家下载使用. 1.首先打开cmd命令窗口,进入我们的工作目录下 执行 cd E:\vu ...
- SpringBoot与Docker1
1:docker是一个开源的应用容器引擎: docker支持将软件编译成一个镜像:然后再镜像中各种软件做好配置,将镜像发布出去,其他使用者可以直接使用这个镜像: 运行中的这个镜像称为容器,容器启动是非 ...
- Java实现递归将嵌套Map里的字段名由驼峰转为下划线
摘要: 使用Java语言递归地将Map里的字段名由驼峰转下划线.通过此例可以学习如何递归地解析任意嵌套的List-Map容器结构. 难度:初级 概述 在进行多语言混合编程时,由于编程规范的不同, 有时 ...