時間模塊,import time 導入模塊後使用html
一、python中時間格式:node
a. 時間戳(timestamp):一般來講,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。咱們運行「type(time.time())」,返回的是float類型。python
b.格式化的時間字符串(Format String)mysql
c.結構化的時間(struct_time):struct_time元組共有9個元素共九個元素:(年,月,日,時,分,秒,一年中第幾周,一年中第幾天,夏令時)c++
1 import time 2 #時間戳 3 print(time.time()) # 結果: 1496626275.947731 4 5 #結構化的時間 6 print(time.localtime()) 7 print(time.localtime().tm_year) 8 print(time.gmtime()) # 等同於time.gmtime(time.time()),能夠填入時間戳,轉換爲格林威治時間 9 ''' 10 結果: 11 time.struct_time(tm_year=2017, tm_mon=6, tm_mday=5, tm_hour=9, tm_min=31, tm_sec=15, tm_wday=0, tm_yday=156, tm_isdst=0) 12 2017 13 time.struct_time(tm_year=2017, tm_mon=6, tm_mday=5, tm_hour=1, tm_min=31, tm_sec=15, tm_wday=0, tm_yday=156, tm_isdst=0) 14 ''' 15 16 #格式化的字符串 17 print(time.strftime('%Y-%m-%d %H:%M:%S')) 18 print(time.strftime('%Y-%m-%d %X')) 19 ''' 20 結果: 21 2017-06-05 09:35:24 22 2017-06-05 09:35:24 23 '''
二、時間格式轉換關係圖git
a.timestamp<-->Format String/struct_timeweb
1 import time 2 #--------------------------按圖1轉換時間 3 # localtime([secs]) 4 # 將一個時間戳轉換爲當前時區的struct_time。secs參數未提供,則以當前時間爲準。 5 print(time.localtime()) 6 print(time.localtime(1473525444.037215)) 7 ''' 8 結果: 9 time.struct_time(tm_year=2017, tm_mon=6, tm_mday=5, tm_hour=9, tm_min=57, tm_sec=44, tm_wday=0, tm_yday=156, tm_isdst=0) 10 time.struct_time(tm_year=2016, tm_mon=9, tm_mday=11, tm_hour=0, tm_min=37, tm_sec=24, tm_wday=6, tm_yday=255, tm_isdst=0) 11 ''' 12 13 # gmtime([secs]) 和localtime()方法相似,gmtime()方法是將一個時間戳轉換爲UTC時區(0時區)的struct_time。 14 15 # mktime(t) : 將一個struct_time轉化爲時間戳。 16 print(time.mktime(time.localtime()))#1473525749.0 17 18 19 # strftime(format[, t]) : 把一個表明時間的元組或者struct_time(如由time.localtime()和 20 # time.gmtime()返回)轉化爲格式化的時間字符串。若是t未指定,將傳入time.localtime()。若是元組中任何一個 21 # 元素越界,ValueError的錯誤將會被拋出。 22 print(time.strftime("%Y-%m-%d %X", time.localtime()))#2016-09-11 00:49:56 23 24 # time.strptime(string[, format]) 25 # 把一個格式化時間字符串轉化爲struct_time。實際上它和strftime()是逆操做。 26 print(time.strptime('2011-05-05 16:37:06', '%Y-%m-%d %X')) 27 # time.struct_time(tm_year=2011, tm_mon=5, tm_mday=5, tm_hour=16, tm_min=37, tm_sec=6, tm_wday=3, tm_yday=125, tm_isdst=-1) 28 #在這個函數中,format默認爲:"%a %b %d %H:%M:%S %Y"。
b.國外通常時間格式轉換asctime/cime算法
1 import time 2 #--------------------------按圖2轉換時間 3 # asctime([t]) : 把一個表示時間的元組或者struct_time表示爲這種形式:'Sun Jun 20 23:21:05 1993'。 4 # 若是沒有參數,將會將time.localtime()做爲參數傳入。 5 print(time.asctime()) # Mon Jun 5 10:05:40 2017 6 7 # ctime([secs]) : 把一個時間戳(按秒計算的浮點數)轉化爲time.asctime()的形式。若是參數未給或者爲 8 # None的時候,將會默認time.time()爲參數。它的做用至關於time.asctime(time.localtime(secs))。 9 print(time.ctime()) # Mon Jun 5 10:05:40 2017 10 print(time.ctime(time.time())) # Mon Jun 5 10:05:40 2017
三、struct_time元組元素結構sql
屬性 值 tm_year(年) 好比2011 tm_mon(月) 1 - 12 tm_mday(日) 1 - 31 tm_hour(時) 0 - 23 tm_min(分) 0 - 59 tm_sec(秒) 0 - 61 tm_wday(weekday) 0 - 6(0表示週日) tm_yday(一年中的第幾天) 1 - 366 tm_isdst(是不是夏令時) 默認爲-1 |
四、time加減shell
1 # timestamp加減單位以秒爲單位 2 import time 3 t1 = time.time() 4 t2 = t1+10 # 加十秒 5 6 print(time.ctime(t1)) # Wed Oct 26 21:15:30 2016 7 print(time.ctime(t2)) # Wed Oct 26 21:15:40 2016
五、其餘用法
1 sleep(secs) 線程推遲指定的時間運行,單位爲秒。
隨機取值模塊,import random導入使用
一、random模塊經常使用方法
1 import random 2 print(random.random()) # (0,1)----float 大於0且小於1之間的小數 3 print(random.randint(1, 3)) # [1,3]大於等於1且小於等於3之間的整數 4 print(random.randrange(1, 3)) # (1,3)大於等於1且小於3之間的整數 5 print(random.choice([1, '23', [4, 5]])) # 1或者23或者[4,5] 6 print(random.sample([1, '23', [4, 5]], 2)) # 列表元素任意2個組合 7 print(random.uniform(1, 3)) # 大於1小於3的小數,如1.927109612082716 8 9 item = [1, 3, 5, 7, 9] 10 random.shuffle(item) # 打亂item的順序,至關於"洗牌" 11 print(item)
二、random模塊應用之生成隨機驗證碼
1 # 方式一 2 def v_code(n=5): 3 res = '' 4 for i in range(n): 5 num = random.randint(0,9) 6 s = chr(random.randint(65,90)) 7 add = random.choice([num,s]) 8 res += str(add) 9 return res 10 print(v_code(6)) 11 12 # 方式2 13 import random, string 14 source = string.digits + string.ascii_lowercase 15 print(''.join(random.sample(source,6)))
與操做系統交互的接口模塊,import os 導入模塊後使用
一、os模塊經常使用方法
1 1、os模塊經常使用方法 2 os.getcwd() 獲取當前工做目錄,即當前python腳本工做的目錄路徑 3 os.chdir("dirname") 改變當前腳本工做目錄;至關於shell下cd 4 os.curdir 返回當前目錄: ('.') 5 os.pardir 獲取當前目錄的父目錄字符串名:('..') 6 os.makedirs('dirname1/dirname2') 可生成多層遞歸目錄 7 os.removedirs('dirname1') 若目錄爲空,則刪除,並遞歸到上一級目錄,如若也爲空,則刪除,依此類推 8 os.mkdir('dirname') 生成單級目錄;至關於shell中mkdir dirname 9 os.rmdir('dirname') 刪除單級空目錄,若目錄不爲空則沒法刪除,報錯;至關於shell中rmdir dirname 10 os.listdir('dirname') 列出指定目錄下的全部文件和子目錄,包括隱藏文件,並以列表方式打印 11 os.remove() 刪除一個文件 12 os.rename("oldname","newname") 重命名文件/目錄 13 os.stat('path/filename') 獲取文件/目錄信息 14 os.sep 輸出操做系統特定的路徑分隔符,win下爲"\\",Linux下爲"/" 15 os.linesep 輸出當前平臺使用的行終止符,win下爲"\t\n",Linux下爲"\n" 16 os.pathsep 輸出用於分割文件路徑的字符串 win下爲;,Linux下爲: 17 os.name 輸出字符串指示當前使用平臺。win->'nt'; Linux->'posix' 18 os.system("bash command") 運行shell命令,直接顯示 19 os.environ 獲取系統環境變量 20 os.path.abspath(path) 返回path規範化的絕對路徑 21 os.path.split(path) 將path分割成目錄和文件名二元組返回 22 os.path.dirname(path) 返回path的目錄。其實就是os.path.split(path)的第一個元素 23 os.path.basename(path) 返回path最後的文件名。如何path以/或\結尾,那麼就會返回空值。即os.path.split(path)的第二個元素 24 os.path.exists(path) 若是path存在,返回True;若是path不存在,返回False 25 os.path.isabs(path) 若是path是絕對路徑,返回True 26 os.path.isfile(path) 若是path是一個存在的文件,返回True。不然返回False 27 os.path.isdir(path) 若是path是一個存在的目錄,則返回True。不然返回False 28 os.path.join(path1[, path2[, ...]]) 將多個路徑組合後返回,第一個絕對路徑以前的參數將被忽略 29 os.path.getatime(path) 返回path所指向的文件或者目錄的最後存取時間 30 os.path.getmtime(path) 返回path所指向的文件或者目錄的最後修改時間 31 os.path.getsize(path) 返回path的大小 32 #在Linux和Mac平臺上,該函數會原樣返回path,在windows平臺上會將路徑中全部字符轉換爲小寫,並將全部斜槓轉換爲飯斜槓。 33 os.path.normcase('c:/windows\\system32\\') 返回'c:\\windows\\system32\\', 34 #規範化路徑,如..和/ 35 os.path.normpath('c://windows\\System32\\../Temp/') 返回'c:\\windows\\Temp' 36 ex1: 37 a='/Users/jieli/test1/\\\a1/\\\\aa.py/../..' 38 print(os.path.normpath(a)) 39 結果: 40 /Users/jieli/test1
二、os模塊應用之系統路徑拼接使用
1 #方式一:推薦使用 2 import os 3 #具體應用 4 import os,sys 5 possible_topdir = os.path.normpath(os.path.join( 6 os.path.abspath(__file__), 7 os.pardir, #上一級 8 os.pardir, 9 os.pardir 10 )) 11 sys.path.insert(0,possible_topdir) 12 print(sys.path) 13 14 #方式二:不推薦使用 15 print(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))) 16 ''' 17 結果: 18 ['D:\\',...] 19 D:\ 20 '''
與操做系統交互的接口模塊,import sys導入模塊後使用, 與os模塊配合使用
一、sys模塊經常使用方法
1 ''' 2 sys.argv 命令行參數List,第一個元素是程序自己路徑 3 sys.exit(n) 退出程序,正常退出時exit(0) 4 sys.version 獲取Python解釋程序的版本信息 5 sys.maxint 最大的Int值 6 sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 7 sys.platform 返回操做系統平臺名稱 8 '''
二、sys模塊應用之進度條
1 import sys,time 2 3 for i in range(50): 4 sys.stdout.write('%s\r' %('#'*i)) 5 sys.stdout.flush() 6 time.sleep(0.1) 7 8 ''' 9 注意:在pycharm中執行無效,請到命令行中以腳本的方式執行 10 '''
subprocess意在替代其餘幾個老的模塊或者函數,好比: os.system、os.spawn、os.popen、commands。
a. call執行命令,返回狀態碼
b. check_call 執行命令,狀態碼爲0返回0,不然拋出異常。
c. check_output 若是狀態碼爲0,返回執行後結果,若是狀態碼非0,拋出異常。
d. Popen 用於執行更復雜的系統命令。
一、subprocess參數詳解
1 ''' 2 args但是字符串或者序列類型(如:list,元組),若是是字符串,要加上shell=True。 3 bufsize:指定緩衝。0 無緩衝,1 行緩衝,其餘 緩衝區大小,負值 系統緩衝(全緩衝) 4 stdin, stdout, stderr分別表示程序的標準輸入、輸出、錯誤文件句柄。他們能夠是PIPE,一個存在的文件描述符或存在的文件對象,也能夠設置爲None,表示從父進程繼承。 5 preexec_fn只在Unix平臺下有效,用於指定一個可執行對象(callable object),它將在子進程運行以前被調用。 6 Close_sfs:在windows平臺下,若是close_fds被設置爲True,則新建立的子進程將不會繼承父進程的輸入、輸出、錯誤管道。因此不能將close_fds設置爲True同時重定向子進程的標準輸入、輸出與錯誤(stdin, stdout, stderr)。 7 shell設爲true,程序將經過shell來執行。 8 cwd用於設置子進程的當前目錄 9 env是字典類型,用於指定子進程的環境變量。若是env = None,子進程的環境變量將從父進程中繼承。 10 Universal_newlines不一樣操做系統下,文本的換行符是不同的。如:windows下用'/r/n'表示換,而Linux下用'/n'。若是將此參數設置爲True,Python統一把這些換行符看成'/n'來處理。 11 startupinfo與createionflags只在windows下有效,它們將被傳遞給底層的CreateProcess()函數,用於設置子進程的一些屬性,如:主窗口的外觀,進程的優先級等等。 12 '''
二、subprocess經常使用方法
1 ''' 2 Popen.poll():用於檢查子進程是否已經結束。設置並返回returncode屬性。 3 4 Popen.wait():等待子進程結束。設置並返回returncode屬性。 5 6 Popen.communicate(input=None):與子進程進行交互。向stdin發送數據,或從stdout和stderr中讀取數據。可選參數input指定發送到子進程的參數。Communicate()返回一個元組:(stdoutdata, stderrdata)。注意:若是但願經過進程的stdin向其發送數據,在建立Popen對象的時候,參數stdin必須被設置爲PIPE。一樣,若是但願從stdout和stderr獲取數據,必須將stdout和stderr設置爲PIPE。 7 8 Popen.send_signal(signal):向子進程發送信號。 9 10 Popen.terminate():中止(stop)子進程。在windows平臺下,該方法將調用Windows API TerminateProcess()來結束子進程。 11 12 Popen.kill():殺死子進程。 13 14 Popen.stdin:若是在建立Popen對象是,參數stdin被設置爲PIPE,Popen.stdin將返回一個文件對象用於策子進程發送指令。不然返回None。 15 16 Popen.stdout:若是在建立Popen對象是,參數stdout被設置爲PIPE,Popen.stdout將返回一個文件對象用於策子進程發送指令。不然返回None。 17 18 Popen.stderr:若是在建立Popen對象是,參數stdout被設置爲PIPE,Popen.stdout將返回一個文件對象用於策子進程發送指令。不然返回None。 19 20 Popen.pid:獲取子進程的進程ID。 21 22 Popen.returncode:獲取進程的返回值。若是進程尚未結束,返回None。 23 24 subprocess.call(*popenargs, **kwargs):運行命令。該函數將一直等待到子進程運行結束,並返回進程的returncode。文章一開始的例子就演示了call函數。若是子進程不須要進行交互,就可使用該函數來建立。 25 26 subprocess.check_call(*popenargs, **kwargs):與subprocess.call(*popenargs, **kwargs)功能同樣,只是若是子進程返回的returncode不爲0的話,將觸發CalledProcessError異常。在異常對象中,包括進程的returncode信息。 27 '''
三、subprocess應用之管道
1 import subprocess 2 3 # res=subprocess.Popen('diasdfasdfr',shell=True, 4 # stderr=subprocess.PIPE, 5 # stdout=subprocess.PIPE) 6 7 # print('=====>',res.stdout.read()) 8 # print('=====>',res.stderr.read().decode('gbk')) 9 10 11 #ls |grep txt$ 12 res1=subprocess.Popen(r'dir E:\wupeiqi\s17\day06',shell=True,stdout=subprocess.PIPE) 13 # print(res1.stdout.read()) 14 15 res=subprocess.Popen(r'findstr txt*',shell=True, 16 stdin=res1.stdout, 17 stderr=subprocess.PIPE, 18 stdout=subprocess.PIPE) 19 20 print('===>',res.stdout.read().decode('gbk')) # 管道取一次就空了 21 # print('===>',res.stdout.read().decode('gbk')) 22 # print('===>',res.stdout.read().decode('gbk')) 23 # print('===>',res.stdout.read().decode('gbk')) 24 # print('===>',res.stdout.read().decode('gbk')) 25 # print('===>',res.stdout.read().decode('gbk')) 26 # print('===>',res.stdout.read().decode('gbk'))
json、pickle、shuelve爲python提供的用於序列化的模塊,eval內置方法能夠將一個字符串轉成python對象,不過,eval方法是有侷限性的,對於普通的數據類型,json.loads和eval都能用,但遇到特殊類型的時候,eval就無論用了,因此eval的重點仍是一般用來執行一個字符串表達式,並返回表達式的值。
import json 導入模塊後使用
一、序列化概念:
咱們把對象(變量)從內存中變成可存儲或傳輸的過程稱之爲序列化,在Python中叫pickling,在其餘語言中也被稱之爲serialization,marshalling,flattening等等,都是一個意思。
二、爲何要用序列化:
a. 保證系統和應用的用戶操做狀態
b. 跨平臺數據交互
三、json序列化:
若是咱們要在不一樣的編程語言之間傳遞對象,就必須把對象序列化爲標準格式,好比XML,但更好的方法是序列化爲JSON,由於JSON表示出來就是一個字符串,能夠被全部語言讀取,也能夠方便地存儲到磁盤或者經過網絡傳輸。JSON不只是標準格式,而且比XML更快,並且能夠直接在Web頁面中讀取,很是方便。
JSON表示的對象就是標準的JavaScript語言的對象,JSON和Python內置的數據類型對應以下:
四、python的json應用流程圖:
1 import json 2 dic = { 3 'name':'alex', 4 'age':9000, 5 'height':'150cm', 6 } 7 8 # 寫入dumps 9 res = json.dumps(dic) 10 with open('a.json', 'w') as f: 11 f.write(res) 12 13 # 讀取loads 14 with open('a.json', 'r') as f: 15 dic = json.loads(f.read()) 16 print(dic, type(dic))
簡單寫法:
1 import json 2 dic = { 3 'name':'alex', 4 'age':9000, 5 'height':'150cm', 6 } 7 # json.dump(dic,open('a.json', 'w')) 寫入dump 8 # res = json.load(open('a.json', 'r')) 讀取/賦值load 9 # print(res)
ps.注意''and"":不管數據是怎樣建立的,只要知足json格式,就能夠json.loads出來,不必定非要dumps的數據才能loads
1 import json 2 #dct="{'1':111}"#json 不認單引號 3 #dct=str({"1":111})#報錯,由於生成的數據仍是單引號:{'one': 1} 4 5 dct='{"1":"111"}' 6 print(json.loads(dct)) 7 8 #conclusion: 9 # 不管數據是怎樣建立的,只要知足json格式,就能夠json.loads出來,不必定非要dumps的數據才能loads
import pickle 導入模塊後使用,僅僅能對python數據類型進行序列化,不能知足跨平臺數據交互
一、pickle應用流程圖:
1 import pickle 2 3 dic={'name':'alvin','age':23,'sex':'male'} 4 5 print(type(dic))#<class 'dict'> 6 7 j=pickle.dumps(dic) 8 print(type(j))#<class 'bytes'> 9 10 11 f=open('序列化對象_pickle','wb')#注意是w是寫入str,wb是寫入bytes,j是'bytes' 12 f.write(j) #-------------------等價於pickle.dump(dic,f) 13 14 f.close() 15 #-------------------------反序列化 16 import pickle 17 f=open('序列化對象_pickle','rb') 18 19 data=pickle.loads(f.read())# 等價於data=pickle.load(f) 20 21 22 print(data['age'])
ps.Pickle的問題和全部其餘編程語言特有的序列化問題同樣,就是它只能用於Python,而且可能不一樣版本的Python彼此都不兼容,所以,只能用Pickle保存那些不重要的數據,不能成功地反序列化也不要緊。
二、pickle應用侷限性:
a.pickle不能與json通用(pickle序列化後,內容爲python的字節碼)
b.pickle序列化def函數時,子序列化執行函數時的內存地址,程序結束後,def函數內存地址失效,不能被再次調用。
1 # a.pickle不能與json通用(pickle序列化後,內容爲python的字節碼) 2 import json 3 import pickle 4 # def func(): 5 # print('from func') 6 7 # json.dumps(func)# 報錯,json不支持python的函數類型 8 # f=pickle.dumps(func) 9 # print(f) 10 11 # pickle序列化def函數時,子序列化執行函數時的內存地址,程序結束後,def函數內存地址失效,不能被再次調用。 12 import json 13 import pickle 14 # def func(): 15 # print('from func') 16 # pickle.dump(func,open('c.pkl','wb')) 17 # res=pickle.load(open('c.pkl','rb')) 18 # print(res) 19 # res()
import shuelve 導入模塊後使用,僅僅能對python數據類型進行序列化,不能知足跨平臺數據交互。shelve模塊比pickle模塊簡單,只有一個open函數,返回相似字典的對象,可讀可寫;key必須爲字符串,而值能夠是python所支持的數據類型。shelve其實用anydbm去建立DB而且管理持久化對象的。
1 import shelve 2 3 f=shelve.open(r'sheve.txt') 4 f['stu1_info']={'name':'egon','age':18,'hobby':['piao','smoking','drinking']} 5 f['stu2_info']={'name':'gangdan','age':53} 6 f['school_info']={'website':'http://www.pypy.org','city':'beijing'} 7 8 print(f['stu1_info']['hobby']) 9 f.close()
結果:
['piao', 'smoking', 'drinking']
xml是實現不一樣語言或程序之間進行數據交換的協議,跟json差很少,但json使用起來更簡單,不過,古時候,在json還沒誕生的黑暗年代,你們只能選擇用xml呀,至今不少傳統公司如金融行業的不少系統的接口還主要是xml。xml的格式以下,就是經過<>節點來區別數據結構的:
1 <?xml version="1.0"?> 2 <data> 3 <country name="Liechtenstein"> 4 <rank updated="yes">2</rank> 5 <year>2008</year> 6 <gdppc>141100</gdppc> 7 <neighbor name="Austria" direction="E"/> 8 <neighbor name="Switzerland" direction="W"/> 9 </country> 10 <country name="Singapore"> 11 <rank updated="yes">5</rank> 12 <year>2011</year> 13 <gdppc>59900</gdppc> 14 <neighbor name="Malaysia" direction="N"/> 15 </country> 16 <country name="Panama"> 17 <rank updated="yes">69</rank> 18 <year>2011</year> 19 <gdppc>13600</gdppc> 20 <neighbor name="Costa Rica" direction="W"/> 21 <neighbor name="Colombia" direction="E"/> 22 </country> 23 </data>
一、遍歷XML文檔的全部內容
1 from xml.etree import ElementTree as ET 2 3 ############ 解析方式一 ############ 4 """ 5 # 打開文件,讀取XML內容 6 str_xml = open('xo.xml', 'r').read() 7 8 # 將字符串解析成xml特殊對象,root代指xml文件的根節點 9 root = ET.XML(str_xml) 10 # 全文搜索 11 # print(root.iter('year')) 12 # 在root的子節點找,只找一個 13 # print(root.find('country')) 14 # 在root的子節點找,找全部 15 # print(root.findall('country')) 16 """ 17 ############ 解析方式二 ############ 18 19 # 直接解析xml文件 20 tree = ET.parse("test.xml") 21 # 獲取xml文件的根節點 22 root = tree.getroot() 23 ### 操做 24 # 頂層標籤 25 print(root.tag) 26 # 遍歷XML文檔的第二層 27 for child in root: 28 # 第二層節點的標籤名稱和標籤屬性 29 print(child.tag, child.attrib) 30 # 遍歷XML文檔的第三層 31 for i in child: 32 # 第二層節點的標籤名稱和內容 33 print(i.tag,i.text) 34 ''' 35 data 36 country {'name': 'Liechtenstein'} 37 rank 2 38 year 2008 39 gdppc 141100 40 neighbor None 41 neighbor None 42 country {'name': 'Singapore'} 43 rank 5 44 year 2011 45 gdppc 59900 46 neighbor None 47 country {'name': 'Panama'} 48 rank 69 49 year 2011 50 gdppc 13600 51 neighbor None 52 neighbor None 53 '''
二、遍歷XML中指定的節點
1 ''' 2 二、遍歷XML中指定的節點 3 ''' 4 from xml.etree import ElementTree as ET 5 ############ 解析方式一 ############ 6 # 直接解析xml文件 7 tree = ET.parse("test.xml") 8 # 獲取xml文件的根節點 9 root = tree.getroot() 10 ### 操做 11 12 # 頂層標籤 13 print(root.tag) 14 15 # 遍歷XML中全部的year節點 16 for node in root.iter('year'): 17 # 節點的標籤名稱和內容 18 print(node.tag, node.text) 19 ''' 20 結果: 21 data 22 year 2008 23 year 2011 24 year 2011 25 '''
三、修改節點內容
a.解析字符串方式,修改,保存
1 from xml.etree import ElementTree as ET 2 3 ############ 解析方式一 ############ 4 5 # 打開文件,讀取XML內容 6 str_xml = open('test.xml', 'r').read() 7 # 將字符串解析成xml特殊對象,root代指xml文件的根節點 8 root = ET.XML(str_xml) 9 ############ 操做 ############ 10 # 頂層標籤 11 print(root.tag) 12 13 # 循環全部的year節點 14 for node in root.iter('year'): 15 # 將year節點中的內容自增一 16 new_year = int(node.text) + 1 17 node.text = str(new_year) 18 19 # 設置屬性 20 node.set('name', 'alex') 21 node.set('age', '18') 22 # 刪除屬性 23 del node.attrib['name'] 24 25 26 ############ 保存文件 ############ 27 # 由於root是ElementTree.Element對象,沒有write方法,只有ElementTree有write方法,能夠將root對應的內存地址內容 28 # 傳給ElementTree,實例化成ElementTree對象,就有write方法了 29 tree = ET.ElementTree(root) 30 tree.write("text_new.xml", encoding='utf-8') # 若是更改內容有中文就須要指定編碼了 31 32 ''' 33 結果: 34 cat text_new.xml 35 <year age="18">2009</year> 36 '''
b.解析文件方式,修改,保存
1 from xml.etree import ElementTree as ET 2 3 ############ 解析方式二 ############ 4 5 # 直接解析xml文件 6 tree = ET.parse("test.xml") 7 # 獲取xml文件的根節點 8 root = tree.getroot() 9 ############ 操做 ############ 10 11 # 頂層標籤 12 print(root.tag) 13 # 循環全部的year節點 14 for node in root.iter('year'): 15 # 將year節點中的內容自增一 16 new_year = int(node.text) + 1 17 node.text = str(new_year) 18 # 設置屬性 19 node.set('name', 'alex') 20 node.set('age', '18') 21 # 刪除屬性 22 del node.attrib['name'] 23 24 25 ############ 保存文件 ############ 26 tree.write("newnew.xml", encoding='utf-8')
四、刪除節點
a.解析字符串方式打開,刪除,保存
1 from xml.etree import ElementTree as ET 2 3 ############ 解析字符串方式打開 ############ 4 5 # 打開文件,讀取XML內容 6 str_xml = open('test.xml', 'r').read() 7 # 將字符串解析成xml特殊對象,root代指xml文件的根節點 8 root = ET.XML(str_xml) 9 ############ 操做 ############ 10 # 頂層標籤 11 print(root.tag) 12 # 遍歷data下的全部country節點 13 for country in root.findall('country'): 14 # 獲取每個country節點下rank節點的內容 15 rank = int(country.find('rank').text) 16 if rank > 50: 17 # 刪除指定country節點 18 root.remove(country) 19 ############ 保存文件 ############ 20 tree = ET.ElementTree(root) 21 tree.write("test_new.xml", encoding='utf-8')
b.解析文件方式打開,刪除,保存
1 from xml.etree import ElementTree as ET 2 3 ############ 解析文件方式 ############ 4 5 # 直接解析xml文件 6 tree = ET.parse("test.xml") 7 8 # 獲取xml文件的根節點 9 root = tree.getroot() 10 11 ############ 操做 ############ 12 13 # 頂層標籤 14 print(root.tag) 15 16 # 遍歷data下的全部country節點 17 for country in root.findall('country'): 18 # 獲取每個country節點下rank節點的內容 19 rank = int(country.find('rank').text) 20 21 if rank > 50: 22 # 刪除指定country節點 23 root.remove(country) 24 25 ############ 保存文件 ############ 26 tree.write("newnew.xml", encoding='utf-8')
五、建立xml文件:類型str 等類 建立字符串有兩種方式生成 a = 'name' a = str("name")
a.建立方式(一):類 Element(標籤,{屬性:值})
1 # 方式一 2 from xml.etree import ElementTree as ET 3 # 建立根節點 4 root = ET.Element("famliy") 5 # 建立節點大兒子 6 son1 = ET.Element('son', {'name': '兒1'}) 7 # 建立小兒子 8 son2 = ET.Element('son', {"name": '兒2'}) 9 # 在大兒子中建立兩個孫子 10 grandson1 = ET.Element('grandson', {'name': '兒11'}) 11 grandson2 = ET.Element('grandson', {'name': '兒12'}) 12 son1.append(grandson1) 13 son1.append(grandson2) 14 # 把兒子添加到根節點中 15 root.append(son1) 16 root.append(son1) 17 tree = ET.ElementTree(root) 18 tree.write('test_new.xml',encoding='utf-8', short_empty_elements=False)
1 # 已有文件,二次建立子節點 2 from xml.etree import ElementTree as ET 3 tree = ET.parse("first.xml") # 直接解析xml格式文件 4 root = tree.getroot() #利用getroot方法獲取根節點 5 # print(root.tag) 6 # print(root.attrib) 7 # print(root.text) 8 # 同 字符串建立的兩種方式來看 xml也有兩種方式建立 9 # 利用 Element類直接建立 ====== 10 son = ET.Element("Biaoqian2",{"key":"value"}) 11 son.text="zhi" 12 ele1 = ET.Element("qq",key2="value2", ) 13 ele1.text="woshizhi" 14 root.append(son) 15 son.append(ele1) 16 tree.write("out2.xml")
b.建立方式(二):利用 makeelement建立 Element類的對象 建立一個新文件
1 # 方式二 2 from xml.etree import ElementTree as ET 3 # 建立根節點 4 root = ET.Element("famliy") 5 # 建立大兒子 6 # son1 = ET.Element('son', {'name': '兒1'}) 7 son1 = root.makeelement('son', {'name': '兒1'}) 8 # 建立小兒子 9 # son2 = ET.Element('son', {"name": '兒2'}) 10 son2 = root.makeelement('son', {"name": '兒2'}) 11 # 在大兒子中建立兩個孫子 12 # grandson1 = ET.Element('grandson', {'name': '兒11'}) 13 grandson1 = son1.makeelement('grandson', {'name': '兒11'}) 14 # grandson2 = ET.Element('grandson', {'name': '兒12'}) 15 grandson2 = son1.makeelement('grandson', {'name': '兒12'}) 16 son1.append(grandson1) 17 son1.append(grandson2) 18 # 把兒子添加到根節點中 19 root.append(son1) 20 root.append(son1) 21 tree = ET.ElementTree(root) 22 tree.write('oooo.xml',encoding='utf-8', short_empty_elements=False)
1 # 已有文件,二次建立子節點 2 from xml.etree import ElementTree as ET 3 tree = ET.parse("first.xml") # 直接解析xml格式文件 4 5 root = tree.getroot() #利用getroot方法獲取根節點 6 print(root.tag) 7 print(root.attrib) 8 print(root.text) 9 10 # 同 字符串建立的兩種方式來看 xml也有兩種方式建立 11 # 12 # 1 利用 makeelement建立 Element類的對象 ===== 13 son = root.makeelement("biaoqian",{"key":"value"}) 14 15 s = son.makeelement("biaoqian2",{"key2":"value"}) #Element類的對象 16 17 son.append(s) #傳入根的兒子的兒子 18 root.append(son) # 傳入根節點下,做爲兒子 19 20 tree.write("out.xml")
c.建立方式(三):SubElement建立
1 from xml.etree import ElementTree as ET 2 3 4 # 建立根節點 5 root = ET.Element("famliy") 6 7 8 # 建立節點大兒子 9 son1 = ET.SubElement(root, "son", attrib={'name': '兒1'}) 10 # 建立小兒子 11 son2 = ET.SubElement(root, "son", attrib={"name": "兒2"}) 12 13 # 在大兒子中建立一個孫子 14 grandson1 = ET.SubElement(son1, "age", attrib={'name': '兒11'}) 15 grandson1.text = '孫子' 16 17 18 et = ET.ElementTree(root) #生成文檔對象 19 et.write("test.xml", encoding="utf-8", xml_declaration=True, short_empty_elements=False)
六、將生成的xml的標籤加縮進後寫入新文件
因爲原生保存的XML時默認無縮進,若是想要設置縮進的話, 須要修改保存方式:
1 from xml.etree import ElementTree as ET 2 from xml.dom import minidom 3 4 5 def prettify(elem): 6 """將節點轉換成字符串,並添加縮進。 7 """ 8 rough_string = ET.tostring(elem, 'utf-8') 9 reparsed = minidom.parseString(rough_string) 10 return reparsed.toprettyxml(indent="\t") 11 12 # 建立根節點 13 root = ET.Element("famliy") 14 15 16 # 建立大兒子 17 # son1 = ET.Element('son', {'name': '兒1'}) 18 son1 = root.makeelement('son', {'name': '兒1'}) 19 # 建立小兒子 20 # son2 = ET.Element('son', {"name": '兒2'}) 21 son2 = root.makeelement('son', {"name": '兒2'}) 22 23 # 在大兒子中建立兩個孫子 24 # grandson1 = ET.Element('grandson', {'name': '兒11'}) 25 grandson1 = son1.makeelement('grandson', {'name': '兒11'}) 26 # grandson2 = ET.Element('grandson', {'name': '兒12'}) 27 grandson2 = son1.makeelement('grandson', {'name': '兒12'}) 28 29 son1.append(grandson1) 30 son1.append(grandson2) 31 32 33 # 把兒子添加到根節點中 34 root.append(son1) 35 root.append(son1) 36 37 38 raw_str = prettify(root) 39 40 f = open("xxxoo.xml",'w',encoding='utf-8') 41 f.write(raw_str) 42 f.close()
優化封裝寫入文件
1 # 函數封裝了 縮進和寫入文件的功能 2 from xml.etree import ElementTree as ET 3 from xml.dom import minidom 4 5 def MyWrite(root, file_path): 6 7 rough_string = ET.tostring(root, 'utf-8') 8 reparsed = minidom.parseString(rough_string) 9 new_str = reparsed.toprettyxml(indent="\t") 10 f = open(file_path, 'w', encoding='utf-8') 11 f.write(new_str) 12 f.close() 13 14 root = ET.Element('family', {"age": "18"}) 15 16 # son = ET.Element('family', {"age": "18"}) 17 # son = root.makeelement('family', {"age": "18"}) 18 # root.append(son) 19 ET.SubElement(root,'family', {"age": "19"}) 20 son = ET.SubElement(root,'family', {"age": "十一"}) 21 ET.SubElement(son,'family', {"age": "1"}) 22 23 # tree = ET.ElementTree(root) 24 # tree.write("out.xml", encoding='utf-8', short_empty_elements=False) 25 # tree.write("out.xml", encoding='utf-8', xml_declaration=True) 26 # ET.tostring() 27 28 MyWrite(root, "nnnnn.xml")
configparser用於處理特定格式的文件,其本質上是利用open來操做文件。import configparser以後調用
配置文件:
# 註釋1 ; 註釋2 [section1] k1 = v1 k2:v2 user=egon age=18 is_admin=true salary=31 [section2] k1 = v1
一、獲取全部節點
1 import configparser 2 obj = configparser.ConfigParser() # 建立編輯對象 3 4 obj.read("test.conf",encoding="utf-8") #讀取 文件 5 ret = obj.sections() # 選項 6 print(ret)
二、獲取指定節點下全部的鍵值對
1 import configparser 2 3 # 獲取指定節點下的鍵值 4 obj = configparser.ConfigParser() # 建立編輯對象 5 6 obj.read("ini",encoding="utf-8") #讀取 文件 7 ret = obj.items("mysql") # 鍵值 # [('client_ip', '10.0.0.1'), ('port', '3306')] 8 print(ret)
三、獲取指定節點下全部的建
1 import configparser 2 obj = configparser.ConfigParser() # 建立編輯對象 3 obj.read("ini",encoding="utf-8") #讀取 文件 4 ret = obj.options("mysql") # 選項下的key ['client_ip', 'port'] 5 print(ret)
四、獲取指定節點下指定key的值
1 obj = configparser.ConfigParser() # 建立編輯對象 2 3 obj.read("ini",encoding="utf-8") #讀取 文件 4 ret = obj.get("mysql","client_ip") # 選項下的key 10.0.0.1 5 # ret = obj.getint("mysql","client_ip") # 選項下的key 10.0.0.1 6 # ret = obj.getfloat("mysql","client_ip") # 選項下的key 值爲float類型 7 # ret = obj.getboolean("mysql","client_ip") # 選項下的的全部key必須都是布爾類型 8 print(ret)
ps.
ret = obj.getfloat("mysql","client_ip") # 選項下的key 值爲float類型
ret = obj.getboolean("mysql","client_ip") # 選項下的的全部key必須是布爾類型
五、檢查、刪除、添加節點
1 import configparser 2 # 檢查 刪除 添加節點 3 obj = configparser.ConfigParser() # 建立編輯對象 4 obj.read("ini",encoding="utf-8") #讀取 文件 5 6 # 檢查 7 has_sec = obj.has_section("mysql1") # false 8 print(has_sec) 9 10 # 添加節點 11 obj.add_section("liujianzuo") 12 obj.add_section("liujianzuo1") 13 obj.add_section("liujianzuo2") 14 obj.write(open("ini","w",encoding="utf-8")) # ['section1', 'section2', 'mysql', 'mysqld', 'liujianzuo', 'liujianzuo1', 'liujianzuo2'] 15 obj.read("ini",encoding="utf-8") 16 ret = obj.sections() 17 print(ret) 18 # 刪除節點 19 obj.remove_section("liujianzuo") 20 obj.remove_section("liujianzuo1") 21 obj.write(open("ini","w",encoding="utf-8")) # ['section1', 'section2', 'mysql', 'mysqld', 'liujianzuo2'] 22 obj.read("ini",encoding="utf-8") 23 ret = obj.sections() 24 print(ret)
六、檢查、刪除、設置指定組內的鍵值對
1 import configparser 2 # 檢查 刪除 添加 指定組內的鍵值對 3 4 obj = configparser.ConfigParser() # 建立編輯對象 5 obj.read("ini",encoding="utf-8") #讀取 文件 6 7 # 檢查 8 has_opt = obj.has_option("mysql","port") 9 print(has_opt) 10 11 # 刪除 12 obj.remove_option("mysql","port") 13 obj.write(open("ini","w",encoding="utf-8")) 14 ret = obj.sections() 15 print(ret) 16 17 # # 設置 18 obj.set("mysql","port","4444") 19 obj.write(open("ini","w",encoding="utf-8")) 20 ret = obj.values() 21 print(ret)
用於加密數據,對比認證。import hashlib以後調用
一、hash:一種算法 ,3.x裏代替了md5模塊和sha模塊,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法。
二、hash特色:
a.內容相同則hash運算結果相同,內容稍微改變則hash值則變
b.不可逆推
c.相同算法:不管校驗多長的數據,獲得的哈希值長度固定。
三、hashlib用法
1 import hashlib 2 3 m = hashlib.md5() # m=hashlib.sha256() 4 5 m.update('hello'.encode('utf8')) 6 print(m.hexdigest()) # 5d41402abc4b2a76b9719d911017c592 7 8 m.update('alvin'.encode('utf8')) 9 10 print(m.hexdigest()) # 92a7e713c30abbb0319fa07da2a5c4af 11 12 m2 = hashlib.md5() 13 m2.update('helloalvin'.encode('utf8')) 14 print(m2.hexdigest()) # 92a7e713c30abbb0319fa07da2a5c4af
ps.
注意:把一段很長的數據update屢次,與一次update這段長數據,獲得的結果同樣
可是update屢次爲校驗大文件提供了可能。
四、加鹽及模擬撞庫反解密
以上加密算法雖然依然很是厲害,但時候存在缺陷,即:經過撞庫能夠反解。因此,有必要對加密算法中添加自定義key再來作加密。
a.加鹽
1 import hashlib 2 # ######## md5 ######## 3 # hash = hashlib.md5('898oaFs09f') 4 ######## 256 ######## 5 hash = hashlib.sha256('898oaFs09f'.encode('utf8')) # 加鹽 6 hash.update('admin') # 更新哈希對象以字符串參數 其實就是你的明文密碼 7 8 # import hashlib 9 # 10 # obj = hashlib.md5( 11 # bytes("salt;%#%salt", encoding="utf-8")) # 這裏是輸入的鹽值 ##建立hash對象,md5:(message-Digest Algorithm 5)消息摘要算法,得出一個128位的密文 12 # print(obj) # <md5 HASH object @ 0x0000000000A1F800> 13 # obj.update(bytes("mypasswd123", encoding="utf-8")) # 更新哈希對象以字符串參數 其實就是你的明文密碼 14 # print(obj.digest()) ##返回摘要,做爲二進制數據字符串值 b'\x04\x80)\x17\\\xf8dPA\xbc\xd9@e\xeb&\x0f' 15 # print(obj.hexdigest()) # 返回十六進制數字字符串 048029175cf8645041bcd94065eb260f
b.模擬撞庫反解密
五、 hmac 模塊:消息認證算法:MAC (Message Authentication Codes) 消息認證碼
python 還有一個 hmac 模塊,它內部對咱們建立 key 和 內容 進行進一步的處理而後再加密
1 import hmac 2 h = hmac.new('wueiqi') 3 h.update('hellowo') 4 print h.hexdigest()
用於便捷記錄日誌且線程安全的模塊。import logging以後調用
一、日誌級別種類:
CRITICAL = 50
FATAL = CRITICAL
ERROR = 40
WARNING = 30
WARN = WARNING
INFO = 20
DEBUG = 10
NOTSET = 0
二、日誌模塊寫法
a.若是不指定filename,則默認打印到終端
b.指定日誌級別:
指定方式:
1:level=10
2:level=logging.ERROR
c.指定日誌級別爲ERROR,則只有ERROR及其以上級別的日誌會被打印
1 import logging 2 3 logging.basicConfig(filename='access.log', 4 format='%(asctime)s - %(name)s - %(levelname)s -%(module)s: %(message)s', 5 datefmt='%Y-%m-%d %H:%M:%S %p', 6 level=10) 7 8 logging.debug('debug') 9 logging.info('info') 10 logging.warning('warning') 11 logging.error('error') 12 logging.critical('critical') 13 logging.log(10,'log') #若是level=40,則只有logging.critical和loggin.error的日誌會被打印
三、日誌模塊可用參數
可在logging.basicConfig()函數中經過具體參數來更改logging模塊默認行爲,可用參數有
filename:用指定的文件名建立FiledHandler(後邊會具體講解handler的概念),這樣日誌會被存儲在指定的文件中。
filemode:文件打開方式,在指定了filename時使用這個參數,默認值爲「a」還可指定爲「w」。
format:指定handler使用的日誌顯示格式。
datefmt:指定日期時間格式。
level:設置rootlogger(後邊會講解具體概念)的日誌級別
stream:用指定的stream建立StreamHandler。能夠指定輸出到sys.stderr,sys.stdout或者文件,默認爲sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。點擊查看更詳細
四、日誌格式詳細:
%(name)s |
Logger的名字,並不是用戶名,詳細查看 |
%(levelno)s |
數字形式的日誌級別 |
%(levelname)s |
文本形式的日誌級別 |
%(pathname)s |
調用日誌輸出函數的模塊的完整路徑名,可能沒有 |
%(filename)s |
調用日誌輸出函數的模塊的文件名 |
%(module)s |
調用日誌輸出函數的模塊名 |
%(funcName)s |
調用日誌輸出函數的函數名 |
%(lineno)d |
調用日誌輸出函數的語句所在的代碼行 |
%(created)f |
當前時間,用UNIX標準的表示時間的浮 點數表示 |
%(relativeCreated)d |
輸出日誌信息時的,自Logger建立以 來的毫秒數 |
%(asctime)s |
字符串形式的當前時間。默認格式是 「2003-07-08 16:49:45,896」。逗號後面的是毫秒 |
%(thread)d |
線程ID。可能沒有 |
%(threadName)s |
線程名。可能沒有 |
%(process)d |
進程ID。可能沒有 |
%(message)s |
用戶輸出的消息 |
高級的 文件、文件夾、壓縮包 處理模塊。import shutil以後調用
一、shutil.copyfileobj(fsrc, fdst[, length]):將文件內容拷貝到另外一個文件中
1 ''' 2 一、shutil.copyfileobj(fsrc, fdst[, length]):將文件內容拷貝到另外一個文件中 3 ''' 4 import shutil 5 shutil.copyfileobj(open('old.xml', 'r'), open('new.xml', 'w'))
二、shutil.copyfile(src, dst):拷貝文件
1 ''' 2 二、shutil.copyfile(src, dst):拷貝文件 3 ''' 4 import shutil 5 shutil.copyfile('f1.log', 'f2.log')
三、shutil.copymode(src, dst):僅拷貝權限。內容、組、用戶均不變
1 ''' 2 三、shutil.copymode(src, dst):僅拷貝權限。內容、組、用戶均不變 3 ''' 4 import shutil 5 shutil.copymode('f1.log', 'f2.log')
四、shutil.copystat(src, dst):拷貝狀態的信息,包括:mode bits, atime, mtime, flags
1 ''' 2 四、shutil.copystat(src, dst):拷貝狀態的信息,包括:mode bits, atime, mtime, flags 3 ''' 4 import shutil 5 shutil.copystat('f1.log', 'f2.log')
五、shutil.copy(src, dst):拷貝文件和權限
1 ''' 2 五、shutil.copy(src, dst):拷貝文件和權限 3 ''' 4 import shutil 5 shutil.copy('f1.log', 'f2.log')
六、shutil.copy2(src, dst):拷貝文件和狀態信息
1 ''' 2 六、shutil.copy2(src, dst):拷貝文件和狀態信息 3 ''' 4 import shutil 5 shutil.copy2('f1.log', 'f2.log')
七、shutil.ignore_patterns(*patterns)
八、shutil.copytree(src, dst, symlinks=False, ignore=None):遞歸的去拷貝文件夾
1 ''' 2 八、shutil.copytree(src, dst, symlinks=False, ignore=None):遞歸的去拷貝文件夾 3 ''' 4 import shutil 5 shutil.copytree('folder1', 'folder2', ignore=shutil.ignore_patterns('*.pyc', 'tmp*')) #目標目錄不能存在,注意對folder2目錄父級目錄要有可寫權限,ignore的意思是排除
1 import shutil 2 shutil.copytree('f1', 'f2', symlinks=True, ignore=shutil.ignore_patterns('*.pyc', 'tmp*'))#一般的拷貝都把軟鏈接拷貝成硬連接,即對待軟鏈接來講,建立新的文件
九、shutil.rmtree(path[, ignore_errors[, onerror]]):遞歸的去刪除文件
1 ''' 2 九、shutil.rmtree(path[, ignore_errors[, onerror]]):遞歸的去刪除文件 3 ''' 4 import shutil 5 shutil.rmtree('folder1') 6 7 # import os,sys 8 # shutil.rmtree(os.path.dirname(__file__)+"/c") # 刪除 c目錄 相似 rm -fr 不存在目錄則報錯
十、shutil.move(src, dst):遞歸的去移動文件,它相似mv命令,其實就是重命名。
1 ''' 2 十、shutil.move(src, dst):遞歸的去移動文件,它相似mv命令,其實就是重命名。 3 ''' 4 import shutil 5 6 shutil.move('folder1', 'folder3') 7 # shutil.move("c","b1") # 剪切c目錄到b目錄下 ,src即c目錄不存在則報錯 ,dst即b目錄不存在就是重命名
十一、shutil.make_archive(base_name, format,...)
a.建立壓縮包並返回文件路徑,例如:zip、tar
b.建立壓縮包並返回文件路徑,例如:zip、tar
1 # 將 /Users/wupeiqi/Downloads/test 下的文件打包放置當前程序目錄 2 import shutil 3 4 ret = shutil.make_archive("wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') 5 6 # 將 /Users/wupeiqi/Downloads/test 下的文件打包放置 /Users/wupeiqi/目錄 7 import shutil 8 9 ret = shutil.make_archive("/Users/wupeiqi/wwwwwwwwww", 'gztar', root_dir='/Users/wupeiqi/Downloads/test') 10 # import os,sys 11 # shutil.make_archive("my_bak","gztar",root_dir=os.path.dirname(__file__)+"/b1") 12 # shutil.make_archive(os.path.dirname(__file__)+"/a/my_bak","gztar",root_dir=os.path.dirname(__file__)+"/b1")
c.shutil 對壓縮包的處理是調用 ZipFile 和 TarFile 兩個模塊來進行的,詳細:
zipfile模塊處理
1 import zipfile 2 3 # 壓縮 4 # z = zipfile.ZipFile('laxi.zip', 'w') 5 # z.write('log.log') 6 # z.write('first.xml') 7 # z.close() 8 9 # 添加一個文件 10 # z = zipfile.ZipFile('laxi.zip', 'a') 11 # z.write('first1.xml') 12 # z.write('a/a') # 將a目和其下面的a文件一同錄壓縮到裏面 若是存在會保存,可是仍然壓縮進入 13 # z.write('b/c') # 將b目錄和其下面的c文件一同壓縮到裏面 14 # z.write('b/b') # 將b目錄和其下面的c文件一同壓縮到裏面 15 # z.close() 16 17 # 解壓 18 # z = zipfile.ZipFile('laxi.zip', 'r') 19 # z.extractall("log.log") # 解藥全部文件到log.log目錄 20 # z.extract("log.log") # 解壓單個文件log.log到當前目錄 文件若是存在也無報錯 21 # z.extract("first.xml") # 解壓單個文件log.log到當前目錄 文件若是存在也無報錯 22 # z.close()
tarfile模塊處理
1 import tarfile,os 2 # 壓縮 3 # tar = tarfile.open("your.tar",'w') # 已存在不報錯 4 # tar.add(os.path.dirname(__file__),arcname="nonosd") #將前面的目錄從新更名爲nonosd目錄名 歸檔到your.tar中 5 # tar.add("first.xml",arcname="first.xml") #將前面的目錄從新更名爲nonosd目錄名 歸檔到your.tar中 6 # tar.close() 7 8 # tar = zipfile.ZipFile('laxi.zip', 'a') 9 # tar.write('first1.xml') 10 # tar.write('a/a') # 將a目和其下面的a文件一同錄壓縮到裏面 若是存在會保存,可是仍然壓縮進入 11 # tar.write('b/c') # 將b目錄和其下面的c文件一同壓縮到裏面 12 # tar.write('b/b') # 將b目錄和其下面的c文件一同壓縮到裏面 13 # tar.close() 14 15 # 壓縮 16 # tar = tarfile.open('your.tar','r') 17 # # print(tar.getmembers()) 18 # print(tar.getnames()) #查看全部的文件名 19 # tar.extract('first.xml') #解壓單個文件 20 # tar.extractall(path="a/") # 解壓全部到 path 21 # tar.close()
詳見http://www.cnblogs.com/wangshuyang/p/6922636.html
一、簡介
面向過程的程序設計的核心是過程(流水線式思惟),過程即解決問題的步驟,面向過程的設計就比如精心設計好一條流水線,考慮周全何時處理什麼東西。
優勢是:極大的下降了程序的複雜度
缺點是:一套流水線或者流程就是用來解決一個問題,生產汽水的流水線沒法生產汽車,即使是能,也得是大改,改一個組件,牽一髮而動全身。
應用場景:一旦完成基本不多改變的場景,著名的例子有Linux內核,git,以及Apache HTTP Server等。
面向對象的程序設計的核心是對象(上帝式思惟),要理解對象爲什麼物,必須把本身當成上帝,上帝眼裏世間存在的萬物皆爲對象,不存在的也能夠創造出來。面向對象的程序設計比如如來設計西遊記,如來要解決的問題是把經書傳給東土大唐,如來想了想解決這個問題須要四我的:唐僧,沙和尚,豬八戒,孫悟空,每一個人都有各自的特徵和技能(這就是對象的概念,特徵和技能分別對應對象的數據屬性和方法屬性),然而這並很差玩,因而如來又安排了一羣妖魔鬼怪,爲了防止師徒四人在取經路上被搞死,又安排了一羣神仙保駕護航,這些都是對象。而後取經開始,師徒四人與妖魔鬼怪神仙交互着直到最後取得真經。如來根本不會管師徒四人按照什麼流程去取。
面向對象的程序設計的
優勢是:解決了程序的擴展性。對某一個對象單獨修改,會馬上反映到整個體系中,如對遊戲中一我的物參數的特徵和技能修改都很容易。
缺點:可控性差,沒法向面向過程的程序設計流水線式的能夠很精準的預測問題的處理流程與結果,面向對象的程序一旦開始就由對象之間的交互解決問題,即使是上帝也沒法預測最終結果。因而咱們常常看到一個遊戲人某一參數的修改極有可能致使陰霸的技能出現,一刀砍死3我的,這個遊戲就失去平衡。
應用場景:需求常常變化的軟件,通常需求的變化都集中在用戶層,互聯網應用,企業內部軟件,遊戲等都是面向對象的程序設計大顯身手的好地方
面向對象的程序設計並非所有。對於一個軟件質量來講,面向對象的程序設計只是用來解決擴展性。
二、類和對象概念
提示:python的class術語與c++有必定區別,與 Modula-3更像。
python中一切皆爲對象,且python3統一了類與類型的概念,類型就是類,因此,無論你信不信,你已經使用了很長時間的類了。
基於面向對象設計一個款遊戲:英雄聯盟,每一個玩家選一個英雄,每一個英雄都有本身的特徵和和技能,特徵即數據屬性,技能即方法屬性,特徵與技能的結合體就一個對象。
從一組對象中提取類似的部分就是類,類全部對象都具備的特徵和技能的結合體
在python中,用變量表示特徵,用函數表示技能,於是類是變量與函數的結合體,對象是變量與方法(指向類的函數)的結合體
補充幾個有意思的點:
garen_hero.Q()稱爲向garen_hero這個對象發送了一條消息,讓他去執行Q這個函數,完成一個功能,相似的有:
garen_hero.W()
garen_hero.E()
garen_hero.R()
一個英雄能夠攻擊另一個英雄,這就是對象之間的交互
garen_hero.attack(Riven)
三、初識類:類是數據與函數的結合,兩者稱爲類的屬性
a.聲明一個類:
1 ''' 2 class 類名: 3 '類的文檔字符串' 4 類體 5 ''' 6 7 #咱們建立一個類 8 class Data: 9 pass
b.類的分類:經典類和新式類
1 大前提: 2 1.只有在python2中才分新式類和經典類,python3中統一都是新式類 3 2.新式類和經典類聲明的最大不一樣在於,全部新式類必須繼承至少一個父類 4 3.全部類甭管是否顯式聲明父類,都有一個默認繼承object父類(講繼承時會講,先記住) 5 在python2中的區分 6 經典類: 7 class 類名: 8 pass 9 10 新式類: 11 class 類名(父類): 12 pass 13 14 在python3中,上述兩種定義方式全都是新式類
c.一個類的示例:
1 class Garen: #定義英雄蓋倫的類,不一樣的玩家能夠用它實例出本身英雄; 2 camp='Demacia' #全部玩家的英雄(蓋倫)的陣營都是Demacia; 3 def attack(self,enemy): #普通攻擊技能,enemy是敵人; 4 enemy.life_value-=self.aggressivity #根據本身的攻擊力,攻擊敵人就減掉敵人的生命值。
四、類的兩種做用:屬性引用和實例化
a.屬性引用
1 # class Chinese: 2 # country='China' 3 # 4 # # Chinese.__init__(p1,'shuyang','18','male') 5 # def __init__(self,name,age,sex): 6 # #p1.Name=name;p1.Age=age,p1.Sex=sex 7 # self.Name=name 8 # self.Age=age 9 # self.Sex=sex 10 # 11 # 12 # def talk(self): 13 # print('talking',self) 14 15 16 #屬性的引用 17 # print(Chinese.country) 18 # print(Chinese.talk) 19 # Chinese.talk(123) 20 # Chinese.x=1 21 # print(Chinese.x) 22 # Chinese.country=123123123123123 23 # print(Chinese.country)
b.實例化
1 class Garen: #定義英雄蓋倫的類,不一樣的玩家能夠用它實例出本身英雄; 2 camp='Demacia' #全部玩家的英雄(蓋倫)的陣營都是Demacia; 3 def __init__(self,nickname,aggressivity=58,life_value=455): #英雄的初始攻擊力58...; 4 self.nickname=nickname #爲本身的蓋倫起個別名; 5 self.aggressivity=aggressivity #英雄都有本身的攻擊力; 6 self.life_value=life_value #英雄都有本身的生命值; 7 def attack(self,enemy): #普通攻擊技能,enemy是敵人; 8 enemy.life_value-=self.aggressivity #根據本身的攻擊力,攻擊敵人就減掉敵人的生命值。 9 10 g1=Garen('草叢倫') #就是在執行Garen.__init__(g1,'草叢倫'),而後執行__init__內的代碼g1.nickname=‘草叢倫’等
ps.self其實就是對象名,實例化成什麼對象,self就表明什麼對象
self的做用是在實例化時自動將對象/實例自己傳給__init__的第一個參數,self能夠是任意名字,可是瞎幾把寫別人就看不懂了。
這種自動傳遞的機制還體如今g1.attack的調用上
五、類的屬性
a.類的屬性查看的兩種方式:
dir(類名):查出的是一個名字列表
類名.__dict__:查出的是一個字典,key爲屬性名,value爲屬性值
b.特殊的類屬性
1 類名.__name__# 類的名字(字符串) 2 類名.__doc__# 類的文檔字符串 3 類名.__base__# 類的第一個父類(在講繼承時會講) 4 類名.__bases__# 類全部父類構成的元組(在講繼承時會講) 5 類名.__dict__# 類的字典屬性 6 類名.__module__# 類定義所在的模塊 7 類名.__class__# 實例對應的類(僅新式類中)
六、對象相關:
對象是關於類而實際存在的一個例子,即實例
1 >>> g1=Garen('草叢倫') #類實例化獲得g1這個實例,基於該實例咱們講解實例相關知識 2 >>> type(g1) #查看g1的類型就是類Garen 3 <class '__main__.Garen'> 4 >>> isinstance(g1,Garen) #g1就是Garen的實例 5 True
a.對象/實例只有一種做用:屬性引用
1 #對象/實例自己其實只有數據屬性 2 >>> g1.nickname 3 '草叢倫' 4 >>> g1.aggressivity 5 58 6 >>> g1.life_value 7 455 8 ''' 9 查看實例屬性 10 一樣是dir和內置__dict__兩種方式 11 特殊實例屬性 12 __class__ 13 __dict__ 14 .... 15 '''
b.綁定方法:對象/實例自己只有數據屬性,可是python的class機制會將類的函數綁定到對象上,稱爲對象的方法,或者叫綁定方法,綁定方法惟一綁定一個對象,同一個類的方法綁定到不一樣的對象上,屬於不一樣的方法,內存地址都不會同樣.
1 >>> g1.attack #對象的綁定方法 2 <bound method Garen.attack of <__main__.Garen object at 0x101348dd8>> 3 4 >>> Garen.attack #對象的綁定方法attack本質就是調用類的函數attack的功能,兩者是一種綁定關係 5 <function Garen.attack at 0x101356620>
ps.對象的綁定方法的特別之處在於:obj.func()會把obj傳給func的第一個參數。
c.對象之間的交互:
1 class Riven: 2 camp='Noxus' #全部玩家的英雄(銳雯)的陣營都是Noxus; 3 def __init__(self,nickname,aggressivity=54,life_value=414): #英雄的初始攻擊力54; 4 self.nickname=nickname #爲本身的銳雯起個別名; 5 self.aggressivity=aggressivity #英雄都有本身的攻擊力; 6 self.life_value=life_value #英雄都有本身的生命值; 7 def attack(self,enemy): #普通攻擊技能,enemy是敵人; 8 enemy.life_value-=self.aggressivity #根據本身的攻擊力,攻擊敵人就減掉敵人的生命值。 9 10 #實例出一個Riven來 11 r1=Riven('銳雯雯') 12 13 #交互:銳雯雯攻擊草叢倫,反之同樣 14 g1.life_value # 結果:455 15 r1.attack(g1) 16 g1.life_value # 結果:401
d.類名稱空間與對象/實例名稱空間
建立一個類就會建立一個類的名稱空間,用來存儲類中定義的全部名字,這些名字稱爲類的屬性
而類有兩種屬性:數據屬性和函數屬性
其中類的數據屬性是共享給全部對象的
1 >>> id(r1.camp) #本質就是在引用類的camp屬性,兩者id同樣 2 4315241024 3 >>> id(Riven.camp) 4 4315241024
而類的函數屬性是綁定到全部對象的:
1 >>> id(r1.attack) 2 4302501512 3 >>> id(Riven.attack) 4 4315244200 5 6 ''' 7 r1.attack就是在執行Riven.attack的功能,python的class機制會將Riven的函數屬性attack綁定給r1,r1至關於拿到了一個指針,指向Riven類的attack功能 8 9 除此以外r1.attack()會將r1傳給attack的第一個參數 10 '''
ps.
建立一個對象/實例就會建立一個對象/實例的名稱空間,存放對象/實例的名字,稱爲對象/實例的屬性
在obj.name會先從obj本身的名稱空間裏找name,找不到則去類中找,類也找不到就找父類...最後都找不到就拋出異常
七、應用實例:
定義銳雯類:
1 class Riven: 2 camp='Noxus' 3 def __init__(self,nickname, 4 aggressivity=54, 5 life_value=414, 6 money=1001, 7 armor=3): 8 self.nickname=nickname 9 self.aggressivity=aggressivity 10 self.life_value=life_value 11 self.money=money 12 self.armor=armor 13 def attack(self,enemy): 14 damage_value=self.aggressivity-enemy.armor 15 enemy.life_value-=damage_value
定義蓋文類:
1 class Garen: 2 camp='Demacia' 3 def __init__(self,nickname, 4 aggressivity=58, 5 life_value=455, 6 money=100, 7 armor=10): 8 self.nickname=nickname 9 self.aggressivity=aggressivity 10 self.life_value=life_value 11 self.money=money 12 self.armor=armor 13 def attack(self,enemy): 14 damage_value=self.aggressivity-enemy.armor 15 enemy.life_value-=damage_value
定義裝備:
1 class BlackCleaver: 2 def __init__(self,price=475,aggrev=9,life_value=100): 3 self.price=price 4 self.aggrev=aggrev 5 self.life_value=life_value 6 def update(self,obj): 7 obj.money-=self.price #減錢 8 obj.aggressivity+=self.aggrev #加攻擊 9 obj.life_value+=self.life_value #加生命值 10 def fire(self,obj): #這是該裝備的主動技能,噴火,燒死對方 11 obj.life_value-=1000 #假設火燒的攻擊力是1000
測試交互:
1 r1=Riven('草叢倫') 2 g1=Garen('蓋文') 3 b1=BlackCleaver() 4 5 print(r1.aggressivity,r1.life_value,r1.money) #r1的攻擊力,生命值,護甲 6 7 if r1.money > b1.price: 8 r1.b1=b1 9 b1.update(r1) 10 11 12 print(r1.aggressivity,r1.life_value,r1.money) #r1的攻擊力,生命值,護甲 13 14 print(g1.life_value) 15 r1.attack(g1) #普通攻擊 16 print(g1.life_value) 17 r1.b1.fire(g1) #用裝備攻擊 18 print(g1.life_value) #g1的生命值小於0就死了