一、python序列化与反序列化
python中用于序列化的模块有两个分别是pickle和json,他们的用法完全一样,区别在与pickle只能用于python之间(其他编程语言无法操作pickle化的文件),而json可以在所有编程语言中通用(如Java、C#、PHP、Python等)。
s = '{"name":"alex", "age":18}' #loads操作时类似字典的字符串中字符串数据必须要用双引号 print(json.loads(s)) #将类字典s反序列化为字典 print(type(json.loads(s))) #打印类型是dict # d = {"name": "alex", "job": "IT"} d = {'name': 'alex', "job": "IT"} print(json.dumps(d)) #将一个字典序列化 print(type(json.dumps(d))) #打印字典序列化后的类型为字符串 s = {'name': 'alex', 'age': 18} json.dump(s, open('db', 'w')) #将字典序列化并写入db文件中 result = json.load(open('db', 'r')) #将db文件中的字符串反序列化 print(result, type(result))
s = '{"name":"alex", "age":18}' #loads操作时类似字典的字符串中字符串数据必须要用双引号 print(pickle.loads(s)) #将类字典s反序列化为字典 print(type(pickle.loads(s))) #打印类型是dict # d = {"name": "alex", "job": "IT"} d = {'name': 'alex', "job": "IT"} print(pickle.dumps(d)) #将一个字典序列化 print(type(pickle.dumps(d))) #打印字典序列化后的类型为字符串 s = {'name': 'alex', 'age': 18} pickle.dump(s, open('db', 'w')) #将字典序列化并写入db文件中 result = pickle.load(open('db', 'r')) #将db文件中的字符串反序列化 print(result, type(result))
二、XML
XML是实现不同语言或程序之间进行数据交换的协议,XML文件格式如下:
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year age="18">2028</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year age="18">2031</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <country name="Panama"> <rank updated="yes">69</rank> <year age="18">2031</year> <gdppc>13600</gdppc> <neighbor direction="W" name="Costa Rica" /> <neighbor direction="E" name="Colombia" /> </country> </data>
1、xml解析
xml的解析方式有两种,分别如下:
#!/usr/bin/python # -*- coding:utf-8 -*- from xml.etree import ElementTree as ET #将字符串解析为xml格式,这种方式默认无法直接保存修改 str_xml = open('xml_test.xml', 'r').read() #打开文件读取xml内容(字符串) root = ET.XML(str_xml) #利用ElementTree.XML将字符串解析成XML格式,root得到文件的根节点
#!/usr/bin/python # -*- coding:utf-8 -*- from xml.etree import ElementTree as ET #直接解析xml文件 tree = ET.parse('xml_test.xml') #利用ElementTree.parse 将文件直接解析成XML格式 root = tree.getroot() #获取XML根节点
2、操作xml
#从硬盘中直接解析xml文件并修改其中的内容 tree = ET.parse('xml_test.xml') root = tree.getroot() #获得根节点 for node in root.iter('year'): #遍历根节点下的year节点 new_year = int(node.text) + 1 #将year节点的文本内容自增1 node.text = str(new_year) #将year节点下的文本内容更新 node.set('name', 'alex') #向year节点中增加属性,name='alex' node.set('age', '18') #向year节点中增加属性,age='18' del node.attrib['name'] #删除year节点属性name tree.write('xml_test.xml') #将修改后的xml重新写入文件
# 打开文件,读取XML内容 str_xml = open('xml_test.xml', 'r').read() # 将字符串解析成xml特殊对象,root代指xml文件的根节点 root = ET.XML(str_xml) # 遍历根节点下的所有country节点 for country in root.findall('country'): # 获取每一个country节点下rank节点的内容 rank = int(country.find('rank').text) if rank > 50: # 删除指定country节点 root.remove(country) ############ 保存文件 ############ tree = ET.ElementTree(root) tree.write("newnew.xml", encoding='utf-8')
3、创建xml文件
from xml.etree import ElementTree as ET #直接解析xml文件 tree = ET.parse('xml_test.xml') #利用ElementTree.parse 将文件直接解析成XML格式 root = tree.getroot() #获取XML根节点 #创建子节点方式一 # son = root.makeelement('eric', {'age': '18', 'job': 'IT'}) #在root节点下创建子节点eric # s = son.makeelement('rain', {'age': '10'}) #在eric节点下再创建子节点rain # s.text = 'hello python' #给子节点rain写入文本内容 # son.append(s) #保存创建的子节点 # root.append(son)
from xml.etree import ElementTree as ET #直接解析xml文件 tree = ET.parse('xml_test.xml') #利用ElementTree.parse 将文件直接解析成XML格式 root = tree.getroot() #获取XML根节点 #创建子节点方式二 son = ET.Element('eric', {'age': '18', 'job': 'IT'}) s = ET.Element('rain', {'age': '10'}) s.text = 'hello python' son.append(s) #向节点中追加子节点 root.append(son) tree.write('new_xml.xml', encoding='utf-8') #保存修改
from xml.etree import ElementTree as ET # 直接创建xml(创建节点方式三) root = ET.Element('dad', {'age': '58'}) #创建根节点 son = ET.SubElement(root, 'son', {'age': '24'}) #创建root的字节点son s = ET.SubElement(son, 's', {'age': '11'}) #创建son的子节点s tree = ET.ElementTree(root) #创建tree用来保存修改 tree.write('new2.xml', encoding='utf-8')
以上的方式一、二是通过操作已有xml文件来接着创建,也可直接创建根节点后直接创建xml文件,方式三为直接创建xml文件。
from xml.etree import ElementTree as ET from xml.dom import minidom def prettify(elem): """将节点转换成字符串,并添加缩进。 """ rough_string = ET.tostring(elem, 'utf-8') reparsed = minidom.parseString(rough_string) return reparsed.toprettyxml(indent="\t") root = ET.Element('dad', {'age': '58'}) # 创建根节点 son = ET.SubElement(root, 'son', {'age': '24'}) # 创建root的字节点son s = ET.SubElement(son, 's', {'age': '11'}) # 创建son的子节点s raw_str = prettify(root) f = open("xxxoo.xml", 'w', encoding='utf-8') f.write(raw_str) f.close()
三、requests初步了解
Requests 是使用 Apache2 Licensed 许可证的 基于Python开发的HTTP 库,其在Python内置模块的基础上进行了高度的封装,从而使得Pythoner进行网络请求时,变得美好了许多,使用Requests可以轻而易举的完成浏览器可有的任何操作。
import requests # 使用requests发送HTTP response = requests.get('http://www.weather.com.cn/adat/sk/101270401.html') response.encoding = 'utf-8' result = response.text print(result)
import requests response = requests.get('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=1214360171') result = response.text node = ET.XML(result) #将字符串解析为xml格式 res = node.text if res == 'Y': print('在线') else: print('离线')
import requests from xml.etree import ElementTree as ET response = requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=T7&UserID=') result = response.text #得到字符串 root = ET.XML(result) #把字符串解析成xml for node in root.iter('TrainDetailInfo'): #遍历根节点下的TrainDetailInfo子节点 print(node.find('TrainStation').text, node.find('StartTime').text) #在TrainDetailInfo子节点下寻找TrainStation和StartTime节点的文本内容
补充:
方式一:使用包管理器安装 pip3 install 模块名 #pip3 install requests 方式二:使用源码安装 1、下载源码 解压: tar -zxvf 模块路径 #tar -zxvf /usr/local/requests.tar.gz 2、进入解压后的目录 执行: python3 setup.py
whl包下载地址:http://www.lfd.uci.edu/~gohlke/pythonlibs/ #pip3 install whl包路径
四、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.copytree(src, dst, symlinks=False, ignore=None)
递归的去拷贝文件夹
import shutil shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))
shutil.rmtree(path[, ignore_errors[, onerror]])
递归的去删除文件
import shutil shutil.rmtree('folder1')
shutil.move(src, dst)
递归的去移动文件,它类似mv命令,其实就是重命名。
import shutil shutil.move('folder1', 'folder3')
shutil.make_archive(base_name, format,...)
创建压缩包并返回文件路径,例如:zip、tar
一些参数含义:
- base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:www =>保存至当前路径
如:/Users/wupeiqi/www =>保存至/Users/document/ - format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
- root_dir: 要压缩的文件夹路径(默认当前目录)
- owner: 用户,默认当前用户
- group: 组,默认当前组
- logger: 用于记录日志,通常是logging.Logger对象
#将 /Users/document/test 下的文件打包放置当前程序目录 import shutil ret = shutil.make_archive("filename", 'gztar', root_dir='/Users/document/test') #将 /Users/document/test 下的文件打包放置 /Users/document目录 import shutil ret = shutil.make_archive("/Users/document/filename", 'gztar', root_dir='/Users/document/test')
zipfile处理压缩包
import zipfile # 压缩文件 z = zipfile.ZipFile('file.zip', 'w') #创建一个压缩包file z.write('ini_new') #将ini_new文件添加至压缩包 z.write('ini') #将ini文件添加至压缩包 z.close() #关闭压缩包
import zipfile z = zipfile.ZipFile('file.zip', 'r') z.extractall() z.close()
tarfile处理压缩包
import tarfile # 压缩 tar = tarfile.open('file.tar', 'w') # 创建一个压缩包 tar.add('log_1.log', arcname='log1.log') # 将log_1.log文件添加到压缩包,并重命名为log1.log tar.add('log_2.log', arcname='log2.log') # 将log_2.log文件添加到压缩包,并重命名为log2.log tar.close()
import tarfile # 解压 tar = tarfile.open('file.tar', 'r') tar.extractall() # 可设置解压地址 tar.close()
五、subprocess模块
subprocess 模块实现执行shell命令的相关的模块和函数的功能,并提供了更丰富的功能。
call
执行命令,返回状态码
ret = subprocess.call(["ls", "-l"], shell=False) ret = subprocess.call("ls -l", shell=True) #设置shell=True,可以吧命令连起来写
check_call
执行命令,如果执行状态码是 0 ,则返回0,否则抛异常
subprocess.check_call(["ls", "-l"]) subprocess.check_call("exit 1", shell=True)
check_output
执行命令,如果状态码是 0 ,则返回执行结果,否则抛异常
subprocess.check_output(["echo", "Hello World!"]) subprocess.check_output("exit 1", shell=True)
subprocess.Popen(...)
用于执行复杂的系统命令
一些参数的含义:
- args:shell命令,可以是字符串或者序列类型(如:list,元组)
- bufsize:指定缓冲。0 无缓冲,1 行缓冲,其他 缓冲区大小,负值 系统缓冲
- stdin, stdout, stderr:分别表示程序的标准输入、输出、错误句柄
- preexec_fn:只在Unix平台下有效,用于指定一个可执行对象(callable object),它将在子进程运行之前被调用
- close_sfs:在windows平台下,如果close_fds被设置为True,则新创建的子进程将不会继承父进程的输入、输出、错误管道。
所以不能将close_fds设置为True同时重定向子进程的标准输入、输出与错误(stdin, stdout, stderr)。 - shell:同上
- cwd:用于设置子进程的当前目录
- env:用于指定子进程的环境变量。如果env = None,子进程的环境变量将从父进程中继承。
- universal_newlines:不同系统的换行符不同,True -> 同意使用 \n
- startupinfo与createionflags只在windows下有效
将被传递给底层的CreateProcess()函数,用于设置子进程的一些属性,如:主窗口的外观,进程的优先级等等
import subprocess ret1 = subprocess.Popen(["mkdir","t1"]) #当前目录下创建t1目录 ret2 = subprocess.Popen("mkdir t2", shell=True) #当前目录下创建t2目录,设置shell=True可以吧命令连起来写
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print('hello')\n") obj.stdin.write("print(hello)") obj.stdin.close() cmd_out = obj.stdout.read() # 获得正确的输出信息 obj.stdout.close() cmd_error = obj.stderr.read() # 获得错误的输出信息 obj.stderr.close() print(cmd_out) # 打印正确的执行结果信息 print(cmd_error) # 打印错误的执行结果信息
六、configparser模块
configparser用于处理特定格式的文件,其本质上是利用open来操作文件。
1、获取所有节点
import configparser con = configparser.ConfigParser() con.read('ini', encoding='utf-8') name = con.sections() # 获得文件的所有节点名 print(name)
2、获取指定节点下所有的键值对
import configparser con = configparser.ConfigParser() con.read('ini', encoding='utf-8') # 获取指定节点下面的键值对 result = con.items('alex') print(result)
3、获取指定节点下所有的建
import configparser con = configparser.ConfigParser() con.read('ini', encoding='utf-8') # 获取指定节点下面的键 result = con.options('alex') print(result)
4、获取指定节点下指定key的值
import configparser con = configparser.ConfigParser() con.read('ini', encoding='utf-8') # 获取指定节点下面的指定键的值 result = con.get('alex', 'age') # result = con.getint('alex', 'age') #获取整数型的值 print(result)
5、检查、删除、添加节点
# 检查是否有该节点 result = con.has_section('alex') print(result) # 添加节点 result = con.add_section('alex') con.write(open('ini_new', 'w')) # 删除节点 result = con.remove_section('eric') con.write(open('ini', 'w'))
6、检查、删除、设置指定组内的键值对
# 检查是否有该节点的键 result = con.has_option('eric', 'age') print(result) # 删除节点 result = con.remove_option('liming', 'age') con.write(open('ini', 'w')) # 设置节点的键值对 result = con.set('liming', 'age', '18') con.write(open('ini', 'w'))
七、 logging模块
用于便捷记录日志且线程安全的模块
import logging logging.basicConfig(filename='log.log', format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', datefmt='%Y-%m-%d %H:%M:%S %p', level=30) logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical') logging.log(10, 'log')
补充:对应的日志级别
CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0
import logging file_1 = logging.FileHandler('log_1.log', 'a') #创建日志文件log_1.log fmt = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s') #创建日志格式 file_1.setFormatter(fmt) #将创建的格式应用与log_1.log日志文件 file_2 = logging.FileHandler('log_2.log', 'a') #创建日志文件log_2.log fmt = logging.Formatter() #创建日志格式,无格式 file_2.setFormatter(fmt) #将创建的无格式应用与log_2.log日志文件 log = logging.Logger('s1', level=logging.ERROR) #制定日志的记录级别和日志别名s1 log.addHandler(file_1) log.addHandler(file_2) log.critical('hello')
注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。
浙公网安备 33010602011771号