瀏覽目錄
一、re模塊
先看一道例題:
我們平時登錄注冊要輸電話號碼,輸入不符合電話號碼規則,就會提示你輸入錯誤。那么怎么判斷電話號碼是否符合輸入條件呢?我們一般都會這樣寫。

while True: phone_number=input("please input your phone nunber:") if len(phone_number) ==11 and phone_number.isdigit() \ and (phone_number.startswith("13") or phone_number.startswith("17") or phone_number.startswith("17") or phone_number.startswith("18")): print("是合法的電話號碼") else: print("是不合法的電話號碼")
是不是感覺還行啊,容易理解,也不難。那咱們看一個更簡單的。
import re phone_number=input("please input your phone number:") if re.match("^(13|14|17|18)[0-9]{9}$",phone_number ): print("是合法的電話號碼") else: print("是不合法的電話號碼")
哇!使用re 模塊方法更簡單。那么我們常用的re方法還有哪些呢?
import re ret=re.findall("a","eva egon yuan") #返回所有滿足匹配條件的結果,放在列表里 print(ret) #結果:['a', 'a'] ret=re.search("a","eva egon yuan").group() print(ret) #結果:a #函數會在字符串內查找模式匹配,直到找到第一個匹配,然后返回一個包含匹配信息的對象, #該對象可以通過調用group()方法得到匹配的字符串,如果字符串沒有匹配,則返回None ret=re.match("a","abc").group() print(ret) #結果:a #同search,不過盡在字符串開始處匹配 ret=re.split("[ab]","abcd") print(ret) #結果:['', '', 'cd'] #先按"a"分割得到""和"bcd",在對""和"bcd"分別按"b"分割 ret=re.sub("\d","H","eva3egon4yuan4",1) print(ret) #結果:evaHegon4yuan4 #將數字替換為"H",參數1表示只替換1個 ret=re.subn("\d","H","eva3egon4yuan4") print(ret) #結果:('evaHegonHyuanH', 3) #將數字替換為"H",返回元組(替換的結果,替換了多少次) obj=re.compile("\d{3}") #將正則表達式編譯成為一個 正則表達式對象,規則要匹配的是3個數字 ret=obj.search("abc123eeee") #正則表達式對象調用search,參數為待匹配的字符串 print(ret.group()) #結果:123 import re ret=re.finditer("\d","ds3sy4784a") print(ret) #<callable_iterator object at 0x000000E6BE57F5F8> print(next(ret).group()) #3 print(next(ret).group()) #4 print([i.group() for i in ret]) #結果:['7', '8', '4'] #查看剩余的左右結果
注意:
1、findall的優先級查詢

import re ret = re.findall('www.(baidu|oldboy).com', 'www.oldboy.com') print(ret) # ['oldboy'] 這是因為findall會優先把匹配結果組里內容返回,如果想要匹配結果,取消權限即可 ret = re.findall('www.(?:baidu|oldboy).com', 'www.oldboy.com') print(ret) # ['www.oldboy.com']
2、split的優先級查詢

import re ret=re.split("\d+","eva3egon4yuan") print(ret) #結果 : ['eva', 'egon', 'yuan'] ret=re.split("(\d+)","eva3egon4yuan") print(ret) #結果 : ['eva', '3', 'egon', '4', 'yuan'] #在匹配部分加上()之后所切出的結果是不同的, #沒有()的沒有保留所匹配的項,但是有()的卻能夠保留了匹配的項, #這個在某些需要保留匹配部分的使用過程是非常重要的。
二、 collections 模塊
python中的擴展數據類型
在內置數據類型(dict、list、set、tuple)的基礎上,collections模塊還提供了幾個額外的數據類型:Counter、deque、defaultdict、namedtuple和OrderedDict等。
1.namedtuple
生成可以使用名字來訪問元素內容的tuple

from collections import namedtuple Point=namedtuple("Point",["x","y"]) p=Point(1,2) print(p) #結果:Point(x=1, y=2)

from collections import namedtuple Circle=namedtuple("circle",["x","y","r"]) d=Circle(2,3,2) print(d) #circle(x=2, y=3, r=2)
2.deque
雙端隊列,可以快速的從另外一側追加和推出對象
使用list存儲數據時,按索引訪問元素很快,但是插入和刪除元素就很慢了,因為list是線性存儲,數據量大的時候,插入和刪除效率很低。
deque是為了高效實現插入和刪除操作的雙向列表,適合用於隊列和棧:

from collections import deque q=deque(["a","b","c"]) q.append("x") q.appendleft("y") print(q) #結果:deque(['y', 'a', 'b', 'c', 'x'])
deque除了實現list的append()
和pop()
外,還支持appendleft()
和popleft()
,這樣就可以非常高效地往頭部添加或刪除元素。

from collections import deque dq = deque([1,2]) dq.append('a') # 從后面放數據 [1,2,'a'] dq.appendleft('b') # 從前面放數據 ['b',1,2,'a'] dq.insert(2,3) #['b',1,3,2,'a'] #2為索引,3為數字 print(dq.pop()) # 從后面取數據 print(dq.pop()) # 從后面取數據 print(dq.popleft()) # 從前面取數據 print(dq) #deque([1, 3])
3.Counter
計數器,主要用來計數

from collections import Counter c=Counter("abhdsfifhabaacsdfgsfa") print(c) #結果:Counter({'a': 5, 'f': 4, 's': 3, 'b': 2, 'd': 2, 'h': 2, 'i': 1, 'c': 1, 'g': 1}) #跟蹤值出現的次數
4.OrderedDict
有序字典
使用dict時,Key是無序的。如果想要保持key的順序,就用OrderedDict。

d=dict([("a","1"),("b",2),("c",3)]) print(d) #結果:{'c': 3, 'b': 2, 'a': '1'} # dict中的Key是無序的

from collections import OrderedDict od=OrderedDict([("a","1"),("b","2"),("c","3")]) print(od) #OrderedDict([('a', '1'), ('b', '2'), ('c', '3')]) #OrderedDict的Key是有序的

od=OrderedDict() od["z"]=1 od["y"]=2 od["x"]=3 print(od.keys()) #結果:odict_keys(['z', 'y', 'x']) #按照插入的key的順序返回
5.defaultdict
帶有默認值的字典

from collections import defaultdict dd=defaultdict(lambda:"N/A") dd["key1"]="abc" print(dd["key1"]) #key1存在 結果:abc print(dd["key2"]) #key2不存在 結果:N/A
三、time模塊
常見的兩種方法
1.time.sleep(secs) (線程)推遲指定的時間運行。單位為秒。 2.time.time() 獲取當前時間戳
表示時間的三種方法
在Python中,通常有這三種方式來表示時間:時間戳、元組(struct_time)、格式化的時間字符串:
(1)時間戳(timestamp) :通常來說,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。我們運行“type(time.time())”,返回的是float類型。
(2)格式化的時間字符串(Format String): ‘1995-10-04’

%y 兩位數的年份表示(00-99) %Y 四位數的年份表示(000-9999) %m 月份(01-12) %d 月內中的一天(0-31) %H 24小時制小時數(0-23) %I 12小時制小時數(01-12) %M 分鍾數(00=59) %S 秒(00-59) %a 本地簡化星期名稱 %A 本地完整星期名稱 %b 本地簡化的月份名稱 %B 本地完整的月份名稱 %c 本地相應的日期表示和時間表示 %j 年內的一天(001-366) %p 本地A.M.或P.M.的等價符 %U 一年中的星期數(00-53)星期天為星期的開始 %w 星期(0-6),星期天為星期的開始 %W 一年中的星期數(00-53)星期一為星期的開始 %x 本地相應的日期表示 %X 本地相應的時間表示 %Z 當前時區的名稱 %% %號本身
(3)元組(struct_time) :struct_time元組共有9個元素共九個元素:(年,月,日,時,分,秒,一年中第幾周,一年中第幾天等)
下面我們來看一下python中表示時間的幾種格式:

#導入時間模塊 >>>import time #時間戳 >>>time.time() 1500875844.800804 #時間字符串 >>>time.strftime("%Y-%m-%d %X") '2017-07-24 13:54:37' >>>time.strftime("%Y-%m-%d %H-%M-%S") '2017-07-24 13-55-04' #時間元組:localtime將一個時間戳轉換為當前時區的struct_time time.localtime() time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=13, tm_min=59, tm_sec=37, tm_wday=0, tm_yday=205, tm_isdst=0)
注:時間戳是計算機能夠識別的時間;時間字符串是人能夠看懂的時間;元組則是用來操作時間的
幾種格式之間的轉化
時間戳與結構化時間轉化

#時間戳-->結構化時間 #time.gmtime(時間戳) #UTC時間,與英國倫敦當地時間一致 #time.localtime(時間戳) #當地時間。例如我們現在在北京執行這個方法:與UTC時間相差8小時,UTC時間+8小時 = 北京時間 >>>time.gmtime(1500000000) time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=2, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0) >>>time.localtime(1500000000) time.struct_time(tm_year=2017, tm_mon=7, tm_mday=14, tm_hour=10, tm_min=40, tm_sec=0, tm_wday=4, tm_yday=195, tm_isdst=0) #結構化時間-->時間戳 #time.mktime(結構化時間) >>>time_tuple = time.localtime(1500000000) >>>time.mktime(time_tuple) 1500000000.0
結構化時間與字符串時間的轉化

#結構化時間-->字符串時間 #time.strftime("格式定義","結構化時間") 結構化時間參數若不傳,則現實當前時間 >>>time.strftime("%Y-%m-%d %X") '2017-07-24 14:55:36' >>>time.strftime("%Y-%m-%d",time.localtime(1500000000)) '2017-07-14' #字符串時間-->結構化時間 #time.strptime(時間字符串,字符串對應格式) >>>time.strptime("2017-03-16","%Y-%m-%d") time.struct_time(tm_year=2017, tm_mon=3, tm_mday=16, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=75, tm_isdst=-1) >>>time.strptime("07/24/2017","%m/%d/%Y") time.struct_time(tm_year=2017, tm_mon=7, tm_mday=24, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=205, tm_isdst=-1)
串時間的轉化

#結構化時間 --> %a %b %d %H:%M:%S %Y串 #time.asctime(結構化時間) 如果不傳參數,直接返回當前時間的格式化串 >>>time.asctime(time.localtime(1500000000)) 'Fri Jul 14 10:40:00 2017' >>>time.asctime() 'Mon Jul 24 15:18:33 2017' #時間戳 --> %a %d %d %H:%M:%S %Y串 #time.ctime(時間戳) 如果不傳參數,直接返回當前時間的格式化串 >>>time.ctime() 'Mon Jul 24 15:19:07 2017' >>>time.ctime(1500000000) 'Fri Jul 14 10:40:00 2017'
來看一道例題:計算時間差

import time true_time=time.mktime(time.strptime('2017-09-11 08:30:00','%Y-%m-%d %H:%M:%S')) time_now=time.mktime(time.strptime('2017-09-12 11:00:00','%Y-%m-%d %H:%M:%S')) dif_time=time_now-true_time struct_time=time.gmtime(dif_time) print('過去了%d年%d月%d天%d小時%d分鍾%d秒'%(struct_time.tm_year-1970,struct_time.tm_mon-1, struct_time.tm_mday-1,struct_time.tm_hour, struct_time.tm_min,struct_time.tm_sec))
四、random模塊
random:隨機數模塊
random模塊中常用的方法

#導入模塊 import random #隨機小數 >>> random.random() # 大於0且小於1之間的小數 0.7664338663654585 >>> random.uniform(1,3) #大於1小於3的小數 1.6270147180533838 #隨機整數 >>> random.randint(1,5) # 大於等於1且小於等於5之間的整數 >>> random.randrange(1,10,2) # 大於等於1且小於10之間的奇數 #隨機選擇一個返回 >>> random.choice([1,'23',[4,5]]) # #1或者23或者[4,5] #隨機選擇多個返回,返回的個數為函數的第二個參數 >>> random.sample([1,'23',[4,5]],2) # #列表元素任意2個組合 [[4, 5], '23'] #打亂列表順序 >>> item=[1,3,5,7,9] >>> random.shuffle(item) # 打亂次序 >>> item [5, 1, 3, 7, 9] >>> random.shuffle(item) >>> item [5, 9, 7, 1, 3]
例:生成隨機驗證碼

import random def v_code(): code="" for i in range(5): num=random.randint(0,9) #生成0-9之間的整數 alf_upper=chr(random.randint(65,90)) #生成65-90之間的整數,轉化成字母 alf_lower = chr(random.randint(97, 122))生成97-122之間的整數,轉化成字母 add=random.choice([num,alf_upper,alf_lower]) #從字母數字中隨機選一個 code="".join([code,str(add)]) return code print(v_code())
五、os模塊
os模塊是與操作系統交互的一個接口
常用方法如下:

''' os.getcwd() 獲取當前工作目錄,即當前python腳本工作的目錄路徑 os.chdir("dirname") 改變當前腳本工作目錄;相當於shell下cd os.curdir 返回當前目錄: ('.') os.pardir 獲取當前目錄的父目錄字符串名:('..') os.makedirs('dirname1/dirname2') 可生成多層遞歸目錄 os.removedirs('dirname1') 若目錄為空,則刪除,並遞歸到上一級目錄,如若也為空,則刪除,依此類推 os.mkdir('dirname') 生成單級目錄;相當於shell中mkdir dirname os.rmdir('dirname') 刪除單級空目錄,若目錄不為空則無法刪除,報錯;相當於shell中rmdir dirname os.listdir('dirname') 列出指定目錄下的所有文件和子目錄,包括隱藏文件,並以列表方式打印 os.remove() 刪除一個文件 os.rename("oldname","newname") 重命名文件/目錄 os.stat('path/filename') 獲取文件/目錄信息 os.sep 輸出操作系統特定的路徑分隔符,win下為"\\",Linux下為"/" os.linesep 輸出當前平台使用的行終止符,win下為"\t\n",Linux下為"\n" os.pathsep 輸出用於分割文件路徑的字符串 win下為;,Linux下為: os.name 輸出字符串指示當前使用平台。win->'nt'; Linux->'posix' os.system("bash command") 運行shell命令,直接顯示 os.popen("bash command).read() 運行shell命令,獲取執行結果 os.environ 獲取系統環境變量 os.path 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所指向的文件或者目錄的最后修改時間 os.path.getsize(path) 返回path的大小 '''
六、sys模塊
sys模塊是與python解釋器交互的一個接口
sys常用方法:

sys.argv 命令行參數List,第一個元素是程序本身路徑 sys.exit(n) 退出程序,正常退出時exit(0),錯誤退出sys.exit(1) sys.version 獲取Python解釋程序的版本信息 sys.path 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 sys.platform 返回操作系統平台名稱

import sys try: sys.exit(1) except SystemExit as e: print(e)
七、序列化模塊
序列化:將原本的字典、列表等內容轉換成一個字符串的過程
序列化的目的:
1、以某種存儲形式使自定義對象持久化;
2、將對象從一個地方傳遞到另一個地方。
3、使程序更具維護性。
優點:通用的序列化模塊
缺點:只有很少的一部分數據類型能夠通過Json轉化成字符串

import json dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = json.dumps(dic) #序列化:將一個字典轉換成一個字符串 print(type(str_dic),str_dic) #<class 'str'> {"k3": "v3", "k1": "v1", "k2": "v2"} #注意,json轉換完的字符串類型的字典中的字符串是由""表示的 dic2 = json.loads(str_dic) #反序列化:將一個字符串格式的字典轉換成一個字典 #注意,要用json的loads功能處理的字符串類型的字典中的字符串必須由""表示 print(type(dic2),dic2) #<class 'dict'> {'k1': 'v1', 'k2': 'v2', 'k3': 'v3'} list_dic = [1,['a','b','c'],3,{'k1':'v1','k2':'v2'}] str_dic = json.dumps(list_dic) #也可以處理嵌套的數據類型 print(type(str_dic),str_dic) #<class 'str'> [1, ["a", "b", "c"], 3, {"k1": "v1", "k2": "v2"}] list_dic2 = json.loads(str_dic) print(type(list_dic2),list_dic2) #<class 'list'> [1, ['a', 'b', 'c'], 3, {'k1': 'v1', 'k2': 'v2'}]

import json f = open('json_file','w') dic = {'k1':'v1','k2':'v2','k3':'v3'} json.dump(dic,f) #dump方法接收一個文件句柄,直接將字典轉換成json字符串寫入文件 f.close() f = open('json_file') dic2 = json.load(f) #load方法接收一個文件句柄,直接將文件中的json字符串轉換成數據結構返回 f.close() print(type(dic2),dic2)
Pickle
優點:所有的python中的數據類型都可以轉化為字符串形式
缺點:pickle序列化的內容只有python能理解,且部分反序列化依賴python代碼。

import pickle dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = pickle.dumps(dic) print(str_dic) #一串二進制內容 dic2 = pickle.loads(str_dic) print(dic2) #字典 import time struct_time = time.localtime(1000000000) print(struct_time) f = open('pickle_file','wb') pickle.dump(struct_time,f) f.close() f = open('pickle_file','rb') struct_time2 = pickle.load(f) print(struct_time2.tm_year)
Shelve
Shelve提供了open方法,是用key來訪問的,使用起來和字典類似。

import shelve f = shelve.open('shelve_file') f['key'] = {'int':10, 'float':9.5, 'string':'Sample data'} #直接對文件句柄操作,就可以存入數據 f.close() import shelve f1 = shelve.open('shelve_file') existing = f1['key'] #取出數據的時候也只需要直接用key獲取即可,但是如果key不存在會報錯 f1.close() print(existing)
這個模塊有個限制,它不支持多個應用同一時間往同一個DB進行寫操作。所以當我們知道我們的應用如果只進行讀操作,我們可以讓shelve通過只讀方式打開DB.

import shelve f = shelve.open('shelve_file', flag='r') existing = f['key'] f.close() print(existing)
由於shelve在默認情況下是不會記錄待持久化對象的任何修改的,所以我們在shelve.open()時候需要修改默認參數,否則對象的修改不會保存。

import shelve f1 = shelve.open('shelve_file') print(f1['key']) f1['key']['new_value'] = 'this was not here before' f1.close() f2 = shelve.open('shelve_file', writeback=True) print(f2['key']) f2['key']['new_value'] = 'this was not here before' f2.close()
writeback方式有優點也有缺點。優點是減少了我們出錯的概率,並且讓對象的持久化對用戶更加的透明了;但這種方式並不是所有的情況下都需要,首先,使用writeback以后,shelf在open()的時候會增加額外的內存消耗,並且當DB在close()的時候會將緩存中的每一個對象都寫入到DB,這也會帶來額外的等待時間。因為shelve沒有辦法知道緩存中哪些對象修改了,哪些對象沒有修改,因此所有的對象都會被寫入。