Python 模块
模块
模块是具有具体功能的代码群
类似于函数式编程和面向过程编程,函数式编程则完成一个功能,其他代码用来调用即可,提供了代码的重用性和代码间的耦合。而对于一个复杂的功能来,可能需要多个函数才能完成(函数又可以在不同的.py文件中),n个 .py 文件组成的代码集合就称为模块。
自定义模块
第三方模块
内置模块
sys.path查找内置模块
import sys for i in sys.path: #查找内置模块 print(i) >>> D:\PythonProject\51CTO\Day6 #pycham自动导入的模块 D:\PythonProject #pycham自动导入的模块 C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\python35.zip C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\DLLs C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\lib #内置模块 C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32 C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\lib\site-packages #第三方模块
导入模块
import ...模块名称
>>> import re >>>
导入模块功能
from...模块名 import ...功能
>>> from time import ctime #当前时间的格式 >>>
>>>from lib.account import login #导入文件夹lib中account文件里的login功能 >>>login() >>>from lib import account #导入文件夹lib中的account模块 >>>account.login
>>>import lib.account
>>>lib.account.login()
利用sys.path导入模块
import sys
sys.path.append("D:/myproject/lib") for i in sys.path: print(i) >>> C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\python35.zip C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\DLLs C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\lib C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32 C:\Users\Administrator\AppData\Roaming\Python\Python35\site-packages C:\Users\Administrator\AppData\Local\Programs\Python\Python35-32\lib\site-packages D:/myproject/lib
time模块
时间相关的操作,时间有三种表示方式:
- 时间戳 1970年1月1日之后的秒,即:time.time()
- 格式化的字符串 2014-11-11 11:11, 即:time.strftime('%Y-%m-%d')
- 结构化时间 元组包含了:年、日、星期等... time.struct_time 即:time.localtime()
导入模块
>>>import time
模块功能
time()
time.time()#打印出自1970年以来至指令输入的间隔时间,单位秒 >>> 1465199016.871012
ctime()
输出当前系统的时间
time.ctime() #返回人类可读模式 >>> Mon Jun 6 15:45:35 2016
time.ctime(time.time())
把时间戳转为当前时间
print(time.ctime(time.time()))#把时间戳转为当前时间 >>> Mon Jun 6 15:48:41 2016 print(time.ctime(time.time()-86640)) #显示昨天同一时间 >>> Sun Jun 5 15:44:41 2016
time.gmtime()
time_obj = time.gmtime(time.time()) print(time_obj) >>> time.struct_time(tm_year=2016, tm_mon=6, tm_mday=6, tm_hour=8, tm_min=10, tm_sec=39, tm_wday=0, tm_yday=158, tm_isdst=0) print(str(time_obj.tm_year) + "-" + str(time_obj.tm_mon) +"-" + str(time_obj.tm_mday)) >>> 2016-6-6
time.localtime()
print(time.localtime(time.time()-86640))#将时间戳转换成struct_time格式,但返回的是本地时间 >>> time.struct_time(tm_year=2016, tm_mon=6, tm_mday=6, tm_hour=14, tm_min=47, tm_sec=40, tm_wday=0, tm_yday=158, tm_isdst=0)
print(time.mktime(time.localtime())) #将time.localtime()功能相反,将struct_time格式装换成时间戳格式 >>> 1465282861.0 print(time.strftime("%Y-%m-%d %H:%M",time.localtime()))#将struct_time格式装换成字符串格式 >>> 2016-06-07 15:01
print(time.strptime("2016-01-28", "%Y-%m-%d"))#将字符串格式转换成struct_time格式 >>> time.struct_time(tm_year=2016, tm_mon=1, tm_mday=28, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=28, tm_isdst=-1)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
print time.time() print time.mktime(time.localtime()) print time.gmtime() #可加时间戳参数 print time.localtime() #可加时间戳参数 print time.strptime('2014-11-11', '%Y-%m-%d') print time.strftime('%Y-%m-%d') #默认当前时间 print time.strftime('%Y-%m-%d',time.localtime()) #默认当前时间 print time.asctime() print time.asctime(time.localtime()) print time.ctime(time.time())
datetime模块
datetime.datetime.now() 当前时间
datetime.timedelta(day=xxx)
import datetime print datetime.datetime.now()
>>>
2016-06-06 16:46:40.520240 print datetime.datetime.now() - datetime.timedelta(days=5)
>>>
2016-06-01 16:46:40.520240
datetime.date()
print(datetime.date.today()) >>> 2016-06-07 print(datetime.date.fromtimestamp(time.time()-86640))#将时间戳转成日期格式 >>> 2016-06-06
.replace()
current_time = datetime.datetime.now() print(current_time.replace(2015, 5, 20))#输出year-month-day,返回当前时间,但指定的值将被替换。
>>>
2015-05-20 15:19:15.608451
时间的加减
datetime.datetime.now() + datetime.timedelta("参数")
参数:day ,week ,month ,yea r,hour ,miniute
newtime = datetime.datetime.now() + datetime.timedelta(days = 10) >>> 2016-06-17 15:29:56.204091 newtime = datetime.datetime.now() + datetime.timedelta(day = -10) >>> 2016-05-28 15:29:56.204091 newtime = datetime.datetime.now() + datetime.timedelta(hours = 10) >>> 2016-06-08 01:29:56.204091 newtime = datetime.datetime.now() + datetime.timedelta(weeks = 10) >>> 2016-08-16 15:29:56.204091
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
import datetime ''' datetime.date:表示日期的类。常用的属性有year, month, day datetime.time:表示时间的类。常用的属性有hour, minute, second, microsecond datetime.datetime:表示日期时间 datetime.timedelta:表示时间间隔,即两个时间点之间的长度 timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]]) strftime("%Y-%m-%d") ''' import datetime print datetime.datetime.now() print datetime.datetime.now() - datetime.timedelta(days=5)
sys模块
sys内置函数
1 sys.argv 命令行参数List,第一个元素是程序本身路径 2 sys.exit(n) 退出程序,正常退出时exit(0) 3 sys.version 获取Python解释程序的版本信息 4 sys.maxint 最大的Int值 5 sys.path 返回模块的搜索路径,初始化时使用PYTHONPATH环境变量的值 6 sys.platform 返回操作系统平台名称 7 sys.stdin 输入相关 8 sys.stdout 输出相关 9 sys.stderror 错误相关
进度条练习
def load_num(): print("processing: ") for i in range(0,101,10): for j in range(2): time.sleep(0.1) sys.stdout.write("#") print("\t" + str(i) + " %" + "\nprocess finished") load_num() >>> processing: ###################### 100 % process finished
def loading(): i = 5 j = "#" for k in range(21): print(str(i*k) + "%" + str(j*k)) time.sleep(0.3) print("process finished") loading() >>> 0% 5%# 10%## 15%### 20%#### 25%##### 30%###### 35%####### 40%######## 45%######### 50%########## 55%########### 60%############ 65%############# 70%############## 75%############### 80%################ 85%################# 90%################## 95%################### 100%#################### process finished
import sys import time def view_bar(num, total): rate = float(num) / float(total) rate_num = int(rate * 100) r = '\r%d%%' % (rate_num, ) sys.stdout.write(r) sys.stdout.flush() if __name__ == '__main__': for i in range(0, 100): time.sleep(0.1) view_bar(i, 100)
os 模块
用于提供系统级别的操作:
os.getcwd() 获取当前工作目录,即当前python脚本工作的目录路径 os.chdir("dirname") 改变当前脚本工作目录;相当于shell下cd os.curdir 返回当前目录: ('.') os.pardir 获取当前目录的父目录字符串名:('..') os.makedirs('dir1/dir2') 可生成多层递归目录 os.removedirs('dirname1') 若目录为空,则删除,并递归到上一级目录,如若也为空,则删除,依此类推 os.mkdir('dirname') 生成单级目录;相当于shell中mkdir dirname os.rmdir('dirname') 删除单级空目录,若目录不为空则无法删除,报错;相当于shell中rmdir dirname os.listdir('dirname') 列出指定目录下的所有文件和子目录,包括隐藏文件,并以列表方式打印 os.remove() 删除一个文件 os.rename("oldname","new") 重命名文件/目录 os.stat('path/filename') 获取文件/目录信息 os.sep 操作系统特定的路径分隔符,win下为"\\",Linux下为"/" os.linesep 当前平台使用的行终止符,win下为"\t\n",Linux下为"\n" os.pathsep 用于分割文件路径的字符串 os.name 字符串指示当前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 运行shell命令,直接显示 os.environ 获取系统环境变量 os.path.abspath(path) 返回path规范化的绝对路径 os.path.split(path) 将path分割成目录和文件名二元组返回 os.path.dirname(path) 返回path的目录。其实就是os.path.split(path)的第一个元素 os.path.basename(path) 返回path最后的文件名。如何path以/或\结尾,那么就会返回空值。即os.path.split(path)的第二个元素 os.path.exists(path) 如果path存在,返回True;如果path不存在,返回False os.path.isabs(path) 如果path是绝对路径,返回True os.path.isfile(path) 如果path是一个存在的文件,返回True。否则返回False os.path.isdir(path) 如果path是一个存在的目录,则返回True。否则返回False os.path.join(path1[, path2[, ...]]) 将多个路径组合后返回,第一个绝对路径之前的参数将被忽略 os.path.getatime(path) 返回path所指向的文件或者目录的最后存取时间 os.path.getmtime(path) 返回path所指向的文件或者目录的最后修改时间
序列化模块 pickle&json
- json 用于【字符串】和 【python基本数据类型】 间进行转换
- pickle 用于【python特有的类型】 和 【python基本数据类型】间进行转换
Json模块提供了四个功能:dumps、dump、loads、load
loads 字符串转字典内部必须是双引号
dumps 字典装换成字符串元素可以是单引号
pickle模块提供了四个功能:dumps、dump、loads、load
pickle的简单应用
pickle.dumps()
import pickle account = { 1000:{ 'name':'python', 'email':'8895465751@qq.com', 'passwd':'abc123', 'balance': 10000, 'phone': 1234567891, 'bank_acc':{ 'icbc':789456123, 'cbc':456123789, 'abc':123456789, }, } } f = open('account.db', 'wb') f.write(pickle.dumps(account)) #pickle.dumps 将数据通过特殊形式转换为只有python认识的字符串 piclke.dump('account.db',f) #pickle.dump直接把数据写入文件中
f.close()
pickle.loads()
import pickle account_file = open("account.db", 'rb') account_dic = pickle.loads(account_file.read()) #pickle.loads读取以pickle.dumps生成的文件 #account_dic = pickle.load(account_file)
account_dic[1000]['balance'] += 5000 account_file.close() f = open('backup_account.db', 'wb') f. write(pickle.dumps(account_dic)) #pickle.dump(account_dic, f) f.close() print(account_dic) >>> {1000: {'bank_acc': {'abc': 123456789, 'icbc': 789456123, 'cbc': 456123789}, 'name': 'alex', 'balance': 15000, 'phone': 1234567891, }
json
json.dumps() #将python的基本数据类型装换成字符串
import json account = { 1000:{ 'name':'python1', 'email':'8895465751@qq.com', 'passwd':'abc123', 'balance': 10000, 'phone': 1234567891, 'bank_acc':{ 'icbc':789456123, 'cbc':456123789, 'abc':123456789, } } } f = open('account.db', 'wb') f.write(bytes(json.dumps(account), encoding = 'UTF-8')) #需从二进制转为‘utf-8’ f.close()
import json user_list = ["alex", "eric", "tony"] s = json.dumps(user_list) print(user_list,type(user_list)) >>> ['alex', 'eric', 'tony'] <class 'list'> print(s, type(s)) >>> ["alex", "eric", "tony"] <class 'str'>
json.loads()
将字符串转换成python的基本数据类型
import json acc_file_name = "account.db" account_file = open(acc_file_name, 'rb') #以二进制读取文件 account_dic = json.loads(account_file.read().decode("utf-8")) #需要转成"utf-8"的码 account_file.close() account_dic["1000"]["balance"] += 5000 #对json的数据进行更改 print(account_dic)
>>>
{'1000': {'phone': 1234567891, 'passwd': 'abc123', 'balance': 15000, 'email': '8895465751@qq.com',
json.loads()
把字符串转换为字典、列表,字典列表元组里面的 元素一定要用双引号" " ,使用单引号或其他符号会报错。
import json resutl = json.loads(s) print(s, type(s)) >>> {"desc":"invilad-citykey", "status":1002} <class 'str'> print(resutl, type(resutl)) >>> {'desc': 'invilad-citykey', 'status': 1002} <class 'dict'> result2 = json.loads(l) print(l, type(l)) >>> [1,22,33,44] <class 'str'> print(result2, type(result2)) >>> [1, 22, 33, 44] <class 'list'>
json.load() 将数据存入文档中
json.dump() 从文档中读取数据
import json dic = {'p2': 'eric', 'p1': 'alex', 'p3': 'tony'} json.dump(dic, open('db', 'w'))#读取内容,将字符串转换为字典 json.load(open('db', 'r')) >>> {'p2': 'eric', 'p1': 'alex', 'p3': 'tony'}
hashlib模块
用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法
import hashlib # ######## md5 ######## hash = hashlib.md5() #md5加密后无法反解 # help(hash.update) hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest()) print(hash.digest())
#MD5加密的基础上再加上自定义码
hash = hashlib.md5(bytes('xxxxx', encoding='utf-8'))
hash.update(bytes('123',encoding='utf-8'))
print(hash.hexcigest())
######## sha1 ######## hash = hashlib.sha1() hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest()) # ######## sha256 ######## hash = hashlib.sha256() hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest()) # ######## sha384 ######## hash = hashlib.sha384() hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest()) # ######## sha512 ######## hash = hashlib.sha512() hash.update(bytes('admin', encoding='utf-8')) print(hash.hexdigest())
以上加密算法虽然依然非常厉害,但时候存在缺陷,即:通过撞库可以反解。所以,有必要对加密算法中添加自定义key再来做加密。
import hashlib # ######## md5 ######## hash = hashlib.md5(bytes('898oaFs09f',encoding="utf-8")) hash.update(bytes('admin',encoding="utf-8")) print(hash.hexdigest())
python内置还有一个 hmac 模块,它内部对我们创建 key 和 内容 进行进一步的处理然后再加密
import hmac h = hmac.new(bytes('898oaFs09f',encoding="utf-8")) h.update(bytes('admin',encoding="utf-8")) print(h.hexdigest())
登录密码加密练习
import hashlib def md5(args): ooo = hashlib.md5(bytes('898oaFs09f', encoding="utf-8")) ooo.update(bytes('admin', encoding="utf-8")) return ooo.hexdigest() def login(user, pwd): with open('db', 'r', encoding='utf-8') as f: for line in f: u,p = line.strip().split('|') if u == user and p == md5(pwd): return True def register(user, pwd): with open('db', 'a', encoding='utf-8') as f: temp = user + "|" + md5(pwd) f.write(temp) def main(): inp = input('1.登录 2.注册') if inp == '2': user = input("用户名:") pwd = input("密码:") register(user, pwd) elif inp == '1': user = input("用户名:") pwd = input("密码:") r = login(user, pwd) if r: print("登录成功") else: print("登录失败") main()
requests模块
Requests可以轻而易举的完成浏览器可有的任何操作。
requests.get()
import urllib.request f = urllib.request.urlopen('http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=424662508') result = f.read().decode('utf-8')
requests.post()
import requests payload = {'key1': 'value1', 'key2': 'value2'} ret = requests.post("http://httpbin.org/post", data=payload) print(ret.text) # 2、发送请求头和数据实例 import requests import json url = 'https://api.github.com/some/endpoint' payload = {'some': 'data'} headers = {'content-type': 'application/json'} ret = requests.post(url, data=json.dumps(payload), headers=headers) print(ret.text) print(ret.cookies)
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
requests.get(url, params=None, **kwargs) requests.post(url, data=None, json=None, **kwargs) requests.put(url, data=None, **kwargs) requests.head(url, **kwargs) requests.delete(url, **kwargs) requests.patch(url, data=None, **kwargs) requests.options(url, **kwargs) # 以上方法均是在此方法的基础上构建 requests.request(method, url, **kwargs)
request.get()
request.text()
import requests response = requests.get("http://www.weather.com.cn/adat/sk/101280701.html") #访问http网页 response.encoding = "utf-8" result = response.text #接收获取的信息 print(result) >>> {"weatherinfo":{"city":"珠海","cityid":"101280701","temp":"22","WD":"东风","WS":"2级","SD":"94%","WSE":"2","time":"10:25","isRadar":"0","Radar":"","njd":"暂无实况","qy":"1007"}}
XML模块
XML是实现不同语言或程序之间进行数据交换的协议,XML文件格式如下:
<data> <country name="Liechtenstein"> <rank updated="yes">2</rank> <year>2023</year> <gdppc>141100</gdppc> <neighbor direction="E" name="Austria" /> <neighbor direction="W" name="Switzerland" /> </country> <country name="Singapore"> <rank updated="yes">5</rank> <year>2026</year> <gdppc>59900</gdppc> <neighbor direction="N" name="Malaysia" /> </country> <country name="Panama"> <rank updated="yes">69</rank> <year>2026</year> <gdppc>13600</gdppc> <neighbor direction="W" name="Costa Rica" /> <neighbor direction="E" name="Colombia" /> </country> </data>
从xml文件中查找节点、属性、文本内容
from xml.etree import ElementTree as ET root = ET.XML(open('first_xml', 'r', encoding='utf8').read()) print(root.tag) #tag为标签信息 >>> data for note in root: #x循环根节点 print("note", note, type(note)) # note获取 子 信息country, country为对象(class)同样tag,attrib,find等功能。 >>> note <Element 'country' at 0x00657E10> <class 'xml.etree.ElementTree.Element'> print("note.tag", note.tag) # note获取 子 信息country的标签 >>> note.tag country print("note.attrib", note.attrib) #note获取 子 信息country的属性,如{'name': 'Liechtenstein'} >>> note.attrib {'name': 'Liechtenstein'} # print(note.tag, note.attrib, note.find('rank').text) print(note.find('year').text) #find获取country的特定属性'year'的text内容 >>> 2023
xml的文件操作
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from xml.etree import ElementTree as ET tree = ET.parse("first_xml") #在内存中 打开并解析文件内容 root = tree.getroot() #获取root信息 for node in root.iter('year'):#获取"year"的信息 print(node) new_year = int(node.text) + 1 #对"year"的信息进行修改 node.text = str(new_year) #对"year"的信息进行修改 node.set('name', 'alex') #增加'year'的属性 <year name="alex">2024</year> del node.attrib['name'] #删除<year name="alex">2024</year>的name属性 tree.write("output.xml") #创建新的xml文件,并把修改的内容保存
from xml.etree import ElementTree as ET tree = ET.parse("first_xml") #在内存中 打开并解析文件内容 root = tree.getroot() #获取root信息 for node in root.iter('year'):#获取"year"的信息 print(node) new_year = int(node.text) + 1 #对"year"的信息进行修改 node.text = str(new_year) #对"year"的信息进行修改 node.set('name', 'alex') #增加'year'的属性 <year name="alex">2024</year> del node.attrib['name'] #删除<year name="alex">2024</year>的name属性 tree.write("output.xml") #创建新的xml文件,并把修改的内容保存
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
from xml.etree import ElementTree as ET tree = ET.parse("first_xml") #在内存中 打开并解析文件内容 root = tree.getroot() #获取root信息 for node in root.iter('year'):#获取"year"的信息 print(node) new_year = int(node.text) + 1 #对"year"的信息进行修改 node.text = str(new_year) #对"year"的信息进行修改 node.set('name', 'alex') #增加'year'的属性 <year name="alex">2024</year> del node.attrib['name'] #删除<year name="alex">2024</year>的name属性 tree.write("output.xml") #创建新的xml文件,并把修改的内容保存
创建XML文件
from xml.etree import ElementTree as ET new_xml = ET.Element("namelist") #创建根节点 #创建根节点的子节点 name1 = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"}) age1 = ET.SubElement(name1, "age", attrib={"checked": "no"}) sex1 = ET.SubElement(name1, "sex", attrib={"sex": "man"}) sex1.text = "33" #创建根节点的子节点 name2 = ET.SubElement(new_xml, "name", attrib={"enrolled": "yes"}) age2 = ET.SubElement(name2, "age") age2.text='19' et = ET.ElementTree(new_xml) #生成新的文档对象 et.write('test.xml', encoding = 'utf-8', xml_declaration = True)
<?xml version='1.0' encoding='utf-8'?> <namelist><name enrolled="yes"><age checked="no" /><sex sex="man">33</sex></name><name enrolled="yes"><age>19</age></name></namelist>
结合requests & xml
import requests r = requests.get("http://www.webxml.com.cn//webservices/qqOnlineWebService.asmx/qqCheckOnline?qqCode=83576041") result = r.text print(result) from xml.etree import ElementTree as ET #解析XML格式内容 #XML接受一个参数:字符串,格式化特殊的对象 node = ET.XML(result) #接受内容 if node.text == 'Y': print("在线") else: print("离线") >>> <?xml version="1.0" encoding="utf-8"?> <string xmlns="http://WebXml.com.cn/">Y</string> 在线
import requests from xml.etree import ElementTree as ET #使用第三方模块requests发送HTTP请求,或者XML格式内容 r = requests.get('http://www.webxml.com.cn/WebServices/TrainTimeWebService.asmx/getDetailInfoByTrainCode?TrainCode=K234&UserID=') result = r.text #解析XML格式内容 root = ET.XML(result) for node in root.iter('TrainDetailInfo'): #root是根的内容,使用root.iter迭代所有的'TrainDetailInfo'进行循环 print(node.tag)#当前节点的名字,获取标签名 >>> TrainDetailInfo print(node.attrib) #把属性组成字典放入attrib里边 >>>{'{urn:schemas-microsoft-com:xml-diffgram-v1}id': 'TrainDetailInfo1', '{urn:schemas-microsoft-com:xml-msdata}rowOrder': '0', '{urn:schemas-microsoft-com:xml-diffgram-v1}hasChanges': 'inserted'} print(node.find('TrainStation').text, node.find('StartTime').text) #获取'TrainStation'和'StartTime'标签的值,text输出内容 >>> 上海(车次:K234\K235) 11:12:00
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
This XML file does not appear to have any style information associated with it. The document tree is shown below. <DataSet xmlns="http://WebXml.com.cn/"> <xs:schema xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" id="getDetailInfo"> <xs:element name="getDetailInfo" msdata:IsDataSet="true" msdata:UseCurrentLocale="true"> <xs:complexType> <xs:choice minOccurs="0" maxOccurs="unbounded"> <xs:element name="TrainDetailInfo"> <xs:complexType> <xs:sequence> <xs:element name="TrainStation" type="xs:string" minOccurs="0"/> <xs:element name="ArriveTime" type="xs:string" minOccurs="0"/> <xs:element name="StartTime" type="xs:string" minOccurs="0"/> <xs:element name="KM" type="xs:short" minOccurs="0"/> </xs:sequence> </xs:complexType> </xs:element> </xs:choice> </xs:complexType> </xs:element> </xs:schema> <diffgr:diffgram xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:diffgr="urn:schemas-microsoft-com:xml-diffgram-v1"> <getDetailInfo xmlns=""> <TrainDetailInfo diffgr:id="TrainDetailInfo1" msdata:rowOrder="0" diffgr:hasChanges="inserted"> <TrainStation>上海(车次:K234\K235)</TrainStation> <ArriveTime/> <StartTime>11:12:00</StartTime> <KM>0</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo2" msdata:rowOrder="1" diffgr:hasChanges="inserted"> <TrainStation>昆山</TrainStation> <ArriveTime>11:45:00</ArriveTime> <StartTime>11:48:00</StartTime> <KM>49</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo3" msdata:rowOrder="2" diffgr:hasChanges="inserted"> <TrainStation>苏州</TrainStation> <ArriveTime>12:12:00</ArriveTime> <StartTime>12:16:00</StartTime> <KM>84</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo4" msdata:rowOrder="3" diffgr:hasChanges="inserted"> <TrainStation>无锡</TrainStation> <ArriveTime>12:44:00</ArriveTime> <StartTime>12:55:00</StartTime> <KM>126</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo5" msdata:rowOrder="4" diffgr:hasChanges="inserted"> <TrainStation>常州</TrainStation> <ArriveTime>13:22:00</ArriveTime> <StartTime>13:26:00</StartTime> <KM>165</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo6" msdata:rowOrder="5" diffgr:hasChanges="inserted"> <TrainStation>镇江</TrainStation> <ArriveTime>14:13:00</ArriveTime> <StartTime>14:16:00</StartTime> <KM>237</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo7" msdata:rowOrder="6" diffgr:hasChanges="inserted"> <TrainStation>南京</TrainStation> <ArriveTime>15:04:00</ArriveTime> <StartTime>15:16:00</StartTime> <KM>301</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo8" msdata:rowOrder="7" diffgr:hasChanges="inserted"> <TrainStation>蚌埠</TrainStation> <ArriveTime>17:27:00</ArriveTime> <StartTime>17:50:00</StartTime> <KM>485</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo9" msdata:rowOrder="8" diffgr:hasChanges="inserted"> <TrainStation>徐州</TrainStation> <ArriveTime>19:38:00</ArriveTime> <StartTime>19:58:00</StartTime> <KM>649</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo10" msdata:rowOrder="9" diffgr:hasChanges="inserted"> <TrainStation>商丘</TrainStation> <ArriveTime>22:12:00</ArriveTime> <StartTime>22:17:00</StartTime> <KM>795</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo11" msdata:rowOrder="10" diffgr:hasChanges="inserted"> <TrainStation>开封</TrainStation> <ArriveTime>23:49:00</ArriveTime> <StartTime>23:53:00</StartTime> <KM>926</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo12" msdata:rowOrder="11" diffgr:hasChanges="inserted"> <TrainStation>郑州</TrainStation> <ArriveTime>00:37:00</ArriveTime> <StartTime>01:14:00</StartTime> <KM>998</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo13" msdata:rowOrder="12" diffgr:hasChanges="inserted"> <TrainStation>新乡</TrainStation> <ArriveTime>02:20:00</ArriveTime> <StartTime>02:22:00</StartTime> <KM>1078</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo14" msdata:rowOrder="13" diffgr:hasChanges="inserted"> <TrainStation>鹤壁</TrainStation> <ArriveTime>03:01:00</ArriveTime> <StartTime>03:03:00</StartTime> <KM>1144</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo15" msdata:rowOrder="14" diffgr:hasChanges="inserted"> <TrainStation>安阳</TrainStation> <ArriveTime>03:33:00</ArriveTime> <StartTime>03:36:00</StartTime> <KM>1185</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo16" msdata:rowOrder="15" diffgr:hasChanges="inserted"> <TrainStation>邯郸</TrainStation> <ArriveTime>04:11:00</ArriveTime> <StartTime>04:16:00</StartTime> <KM>1245</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo17" msdata:rowOrder="16" diffgr:hasChanges="inserted"> <TrainStation>邢台</TrainStation> <ArriveTime>04:47:00</ArriveTime> <StartTime>04:51:00</StartTime> <KM>1297</KM> </TrainDetailInfo> <TrainDetailInfo diffgr:id="TrainDetailInfo18" msdata:rowOrder="17" diffgr:hasChanges="inserted"> <TrainStation>石家庄</TrainStation> <ArriveTime>06:05:00</ArriveTime> <StartTime/> <KM>1406</KM> </TrainDetailInfo> </getDetailInfo> </diffgr:diffgram> </DataSet>
configparser
configparser用于处理特定格式的文件,其本质上是利用open来操作文件。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 注释1 ; 注释2 [section1] # 节点 k1 = v1 # 值 k2:v2 # 值 [section2] # 节点 k1 = v1 # 值 指定格式
1、获取所有节点
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') ret = config.sections() print(ret)
2、获取指定节点下所有的键值对
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') ret = config.items('section1') print(ret)
3、获取指定节点下所有的建
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') ret = config.options('section1') print(ret)
4、获取指定节点下指定key的值
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') v = config.get('section1', 'k1') # v = config.getint('section1', 'k1') # v = config.getfloat('section1', 'k1') # v = config.getboolean('section1', 'k1')
5、检查、删除、添加节点
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') # 检查 has_sec = config.has_section('section1') print(has_sec) # 添加节点 config.add_section("SEC_1") config.write(open('xxxooo', 'w')) # 删除节点 config.remove_section("SEC_1") config.write(open('xxxooo', 'w'))
6、检查、删除、设置指定组内的键值对
import configparser config = configparser.ConfigParser() config.read('xxxooo', encoding='utf-8') # 检查 has_opt = config.has_option('section1', 'k1') print(has_opt) # 删除 config.remove_option('section1', 'k1') config.write(open('xxxooo', 'w')) # 设置 config.set('section1', 'k10', "123") config.write(open('xxxooo', 'w'))
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*'))
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
创建压缩包并返回文件路径,例如:zip、tar
- base_name: 压缩包的文件名,也可以是压缩包的路径。只是文件名时,则保存至当前目录,否则保存至指定路径,
如:www =>保存至当前路径
如:/Users/wupeiqi/www =>保存至/Users/wupeiqi/ - format: 压缩包种类,“zip”, “tar”, “bztar”,“gztar”
- root_dir: 要压缩的文件夹路径(默认当前目录)
- owner: 用户,默认当前用户
- group: 组,默认当前组
- logger: 用于记录日志,通常是logging.Logger对象
将 /Users/wupeiqi/Downloads/test 下的文件打包放置当前程序目录 import shutil ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') #将 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目录 import shutil ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test')
shutil 对压缩包的处理是调用 ZipFile 和 TarFile 两个模块来进行的,详细:
import zipfile z = zipfile.ZipFile('ZIP_FILE.zip', 'a') z.write('test2.xml') z.close() z = zipfile.ZipFile("test_zip.zip", 'w') z.write('test2.xml') z.write('out.xml') z.close() z = zipfile.ZipFile("test_zip.zip", 'r') z.extractall() z.namelist() z.extract('out.xml') z.close()
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
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() zipfile解压缩
import tarfile # 压缩 tar = tarfile.open('your.tar','w') tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log') tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log') tar.close() # 解压 tar = tarfile.open('your.tar','r') tar.extractall() # 可设置解压地址 tar.close() tarfile解压缩
logging
logging模块提供日志功能
logger通过logger.setLevel(lvl)来设置,等级DEBUG<CRITIAL<WARNING。
logging.debug()、logging.info()、logging.warning()、logging.error()、logging.critical():设定root logger的日志级别
logging.basicConfig() 函数对日志的输出格式及方式做相关配置
logging.getLogger([name]):返回一个logger对象,如果没有指定名字将返回root logger
1、单文件日志
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=10)
level = logging.INFO)#level=INFO=10 logging.debug('debug') logging.info('info') logging.warning('warning') logging.error('error') logging.critical('critical') logging.log(10,'log')
logging.log(logging.INFO, '333')#设定loggin.log的level为INFO,message为333
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
2016-06-16 15:26:56 PM - root - CRITICAL -logging_learn: critial 2016-06-16 15:26:56 PM - root - DEBUG -logging_learn: debug 2016-06-16 15:26:56 PM - root - INFO -logging_learn: info 2016-06-16 15:26:56 PM - root - WARNING -logging_learn: warning 2016-06-16 15:26:56 PM - root - CRITICAL -logging_learn: critical 2016-06-16 15:26:56 PM - root - DEBUG -logging_learn: log
日志等级:
CRITICAL = 50 FATAL = CRITICAL ERROR = 40 WARNING = 30 WARN = WARNING INFO = 20 DEBUG = 10 NOTSET = 0
注:只有【当前写等级】大于【日志等级】时,日志文件才被记录。
日志记录格式:
2、多文件日志
对于上述记录日志的功能,只能将日志记录在单文件中,如果想要设置多个日志文件,logging.basicConfig将无法完成,需要自定义文件和日志操作对象。
日志(一)
# 定义文件 file_1_1 = logging.FileHandler('l1_1.log', 'a') fmt = logging.Formatter(fmt="%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s") file_1_1.setFormatter(fmt) file_1_2 = logging.FileHandler('l1_2.log', 'a') fmt = logging.Formatter() file_1_2.setFormatter(fmt) # 定义日志 logger1 = logging.Logger('s1', level=logging.ERROR) logger1.addHandler(file_1_1) logger1.addHandler(file_1_2) # 写日志 logger1.critical('1111')
日志(二) # 定义文件 file_2_1 = logging.FileHandler('l2_1.log', 'a') fmt = logging.Formatter() file_2_1.setFormatter(fmt) # 定义日志 logger2 = logging.Logger('s2', level=logging.INFO) logger2.addHandler(file_2_1)
如上述创建的两个日志对象
- 当使用【logger1】写日志时,会将相应的内容写入 l1_1.log 和 l1_2.log 文件中
- 当使用【logger2】写日志时,会将相应的内容写入 l2_1.log 文件中
更多logging模块学习:http://www.cnblogs.com/dkblog/archive/2011/08/26/2155018.html
subprocess系统命令
call
执行命令,返回状态码
ret = subprocess.call(["ls", "-l"], shell=False) ret = subprocess.call("ls -l", 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"]) ret2 = subprocess.Popen("mkdir t2", shell=True)
终端输入的命令分为两种:
- 输入即可得到输出,如:ifconfig
- 输入进行某环境,依赖再输入,如:python
import subprocess obj = subprocess.Popen("mkdir t3", shell=True, cwd='/home/dev',)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") 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)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) obj.stdin.write("print(1)\n") obj.stdin.write("print(2)") out_error_list = obj.communicate() print(out_error_list)
import subprocess obj = subprocess.Popen(["python"], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True) out_error_list = obj.communicate('print("hello")') print(out_error_list)