一、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))    
json
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))  
pickle

二、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>
xml

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根节点
方式二:直接以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文件并修改其中的内容
# 打开文件,读取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')
字符串解析成xml特殊对象并修改保存

 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()
让创建的xml自动增加缩进

三、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('离线')
判断QQ是否在线
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)  # 打印错误的执行结果信息
在python终端下执行命令

 六、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')
多文件日志

注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。

 

posted on 2016-05-26 18:13  雷雷嘎嘎  阅读(92)  评论(0)    收藏  举报