一 time模塊(時間模塊)★★★★
時間表現形式
在Python中,通常有這三種方式來表示時間:時間戳、元組(struct_time)、格式化的時間字符串:
(1)時間戳(timestamp) :通常來說,時間戳表示的是從1970年1月1日00:00:00開始按秒計算的偏移量。我們運行“type(time.time())”,返回的是float類型。
(2)格式化的時間字符串(Format String): ‘1988-03-16’
(3)元組(struct_time) :struct_time元組共有9個元素共九個元素:(年,月,日,時,分,秒,一年中第幾周,一年中第幾天等)
import time res=type(time.time()) #我們運行“type(time.time())”,返回的是float類型 print(res) #打印結果 <class 'float'> 時間戳 import time print(time.time()) #返回當前時間的時間戳 從1970年到現在時間的總秒數 #打印結果 1493204066.464622 時間字符串 import time res=time.strftime("%Y-%m-%d %X") #返回當前時間,按年-月-日 時分秒顯示,中間的連接符自定義 print(res) #打印結果 2017-04-26 18:54:48 時間元組 import time res=time.localtime() #返回 年,月,日,時,分,秒,一年中第幾周,一年中第幾天,夏令時 print(res) 打印結果 time.struct_time(tm_year=2017, tm_mon=4, tm_mday=26, tm_hour=18, tm_min=55, tm_sec=7, tm_wday=2, tm_yday=116, tm_isdst=0)
小結:時間戳是計算機能夠識別的時間;時間字符串是人能夠看懂的時間;元組則是用來操作時間的
幾種時間形式的轉換
⑴
式的轉換 #1,時間戳<---->結構化時間: localtime/gmtime mktime import time a1=time.localtime(3600*24) a2=time.gmtime(3600*24) print(a1) print(a2) a3=time.mktime(time.localtime()) print(a3) #2,字符串時間<---->結構化時間: strftime/strptime import time a1=time.strftime("%Y-%m-%d %X", time.localtime()) a2=time.strptime("2017-03-16","%Y-%m-%d") print(a1) print(a2
⑵
>>> time.asctime(time.localtime(312343423)) 'Sun Nov 25 10:03:43 1979' >>> time.ctime(312343423) 'Sun Nov 25 10:03:43 1979'
1 #--------------------------其他方法 2 # sleep(secs) 3 # 線程推遲指定的時間運行,單位為秒。
二 random模塊(隨機數模塊)★★
1 >>> import random 2 >>> random.random() # 大於0且小於1之間的小數 3 0.7664338663654585 4 5 >>> random.randint(1,5) # 大於等於1且小於等於5之間的整數 6 7 >>> random.randrange(1,3) # 大於等於1且小於3之間的整數 8 9 >>> random.choice([1,'23',[4,5]]) # #1或者23或者[4,5] 10 11 >>> random.sample([1,'23',[4,5]],2) # #列表元素任意2個組合 12 [[4, 5], '23'] 13 14 >>> random.uniform(1,3) #大於1小於3的小數 15 1.6270147180533838 16 17 >>> item=[1,3,5,7,9] 18 >>> random.shuffle(item) # 打亂次序 19 >>> item 20 [5, 1, 3, 7, 9] 21 >>> random.shuffle(item) 22 >>> item 23 [5, 9, 7, 1, 3]

1 import random 2 3 def v_code(): 4 5 code = '' 6 for i in range(5): 7 8 num=random.randint(0,9) 9 alf=chr(random.randint(65,90)) 10 add=random.choice([num,alf]) 11 code="".join([code,str(add)]) 12 13 return code 14 15 print(v_code())

1 #生成驗證碼2 2 3 def validate(): 4 s="" 5 for i in range(5): 6 rNum=random.randint(0,9) 7 r_alph=chr(random.randint(65,90)) 8 9 ret=random.choice([str(rNum),r_alph]) 10 s+=ret 11 12 return s 13 14 print(val
三 hashlib(摘要算法)★★
算法介紹
Python的hashlib提供了常見的摘要算法,如MD5,SHA1等等。
什么是摘要算法呢?摘要算法又稱哈希算法、散列算法。它通過一個函數,把任意長度的數據轉換為一個長度固定的數據串(通常用16進制的字符串表示)。
摘要算法就是通過摘要函數f()對任意長度的數據data計算出固定長度的摘要digest,目的是為了發現原始數據是否被人篡改過。
摘要算法之所以能指出數據是否被篡改過,就是因為摘要函數是一個單向函數,計算f(data)很容易,但通過digest反推data卻非常困難。而且,對原始數據做一個bit的修改,都會導致計算出的摘要完全不同。
我們以常見的摘要算法MD5為例,計算出一個字符串的MD5值:
#常見摘要算法 MD5 import hashlib m=hashlib.md5() m.update("alex".encode("utf8")) #534b44a19bf18d20b71ecc4eb77c572f print(m.hexdigest()) m.update("alex".encode("utf8")) #alexalex print(m.hexd
如果數據量很大,可以分塊多次調用update(),最后計算的結果是一樣的:
m.update("alex".encode("utf8")) #alexalex print(m.hexdigest())
MD5是最常見的摘要算法,速度很快,生成結果是固定的128 bit字節,通常用一個32位的16進制字符串表示。另一種常見的摘要算法是SHA1,調用SHA1和調用MD5完全類似:
#另一種常見的摘要算法是SHA1 import hashlib sha1 = hashlib.sha1() sha1.update('how to use sha1 in '.encode("utf8")) sha1.update('python hashlib?'.encode("utf8")) print(sha1.hexdigest())
SHA1的結果是160 bit字節,通常用一個40位的16進制字符串表示。比SHA1更安全的算法是SHA256和SHA512,不過越安全的算法越慢,而且摘要長度更長。
摘要算法應用
任何允許用戶登錄的網站都會存儲用戶登錄的用戶名和口令。如何存儲用戶名和口令呢?方法是存到數據庫表中:
name | password --------+---------- michael | 123456 bob | abc999 alice | alice2008
如果以明文保存用戶口令,如果數據庫泄露,所有用戶的口令就落入黑客的手里。此外,網站運維人員是可以訪問數據庫的,也就是能獲取到所有用戶的口令。正確的保存口令的方式是不存儲用戶的明文口令,而是存儲用戶口令的摘要,比如MD5:
username | password ---------+--------------------------------- michael | e10adc3949ba59abbe56e057f20f883e bob | 878ef96e86145580c38c87f0410ad153 alice | 99b1c2188db85afee403b1536010c2c9
考慮這么個情況,很多用戶喜歡用123456,888888,password這些簡單的口令,於是,黑客可以事先計算出這些常用口令的MD5值,得到一個反推表:
'e10adc3949ba59abbe56e057f20f883e': '123456' '21218cca77804d2ba1922c33e0151105': '888888' '5f4dcc3b5aa765d61d8327deb882cf99': 'password'
這樣,無需破解,只需要對比數據庫的MD5,黑客就獲得了使用常用口令的用戶賬號。
對於用戶來講,當然不要使用過於簡單的口令。但是,我們能否在程序設計上對簡單口令加強保護呢?
由於常用口令的MD5值很容易被計算出來,所以,要確保存儲的用戶口令不是那些已經被計算出來的常用口令的MD5,這一方法通過對原始口令加一個復雜字符串來實現,俗稱“加鹽”:
hashlib.md5("salt".encode("utf8"))
經過Salt處理的MD5口令,只要Salt不被黑客知道,即使用戶輸入簡單口令,也很難通過MD5反推明文口令。
但是如果有兩個用戶都使用了相同的簡單口令比如123456,在數據庫中,將存儲兩條相同的MD5值,這說明這兩個用戶的口令是一樣的。有沒有辦法讓使用相同口令的用戶存儲不同的MD5呢?
如果假定用戶無法修改登錄名,就可以通過把登錄名作為Salt的一部分來計算MD5,從而實現相同口令的用戶也存儲不同的MD5。
摘要算法在很多地方都有廣泛的應用。要注意摘要算法不是加密算法,不能用於加密(因為無法通過摘要反推明文),只能用於防篡改,但是它的單向計算特性決定了可以在不存儲明文口令的情況下驗證用戶口令。
四 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.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所指向的文件或者目錄的最后修改時間 os.path.getsize(path) 返回path的大小 '''

1 import os 2 3 print(os.getcwd()) 4 5 f=open("test.txt","w") 6 7 os.chdir(r"C:\Users\Administrator\PycharmProjects\py_fullstack_s4\day32") # cd 8 9 f=open("test2.txt","w") 10 11 print(os.getcwd()) 12 13 14 os.makedirs("aaaaa/bbb") 15 os.removedirs("aaaaa/bbb") 16 17 print(os.listdir(r"C:\Users\Administrator\PycharmProjects\py_fullstack_s4\day33")) 18 19 print(os.stat(r"C:\Users\Administrator\PycharmProjects\py_fullstack_s4\day33\test.txt")) 20 21 22 ''' 23 os.stat_result(st_mode=33206, st_ino=10133099161702379, st_dev=3233102476, st_nlink=1, st_uid=0, st_gid=0, st_size=0, st_atime=1493176560, st_mtime=1493176614, st_ctime=1493176560) 24 25 ''' 26 27 "yuan"+os.sep+"image" 28 29 print(os.name) 30 print(os.system("dir")) 31 32 abs=os.path.abspath("test.txt") 33 print(os.path.basename(abs)) 34 print(os.path.dirname(abs)) 35 36 s1=r"C:\Users\Administrator\PycharmProjects" 37 38 s2=r"py_fullstack_s4\day33" 39 40 print(s1+os.sep+s2) 41 42 ret=os.path.join(s1,s2) # 推薦方式 43 print(
五 sys模塊★★★
print(sys.argv) #命令行參數List,第一個元素是程序本身路徑 print(sys.exit(n)) #退出程序,正常退出時exit(0) print(sys.version) #獲取Python解釋程序的版本信息 print(sys.maxint) #最大的Int值 print(sys.path) #返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 print(sys.platform) #返回操作系統平台名稱
六 logging模塊(日志模塊)★★★★★
函數式簡單配置
import logging logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
默認情況下Python的logging模塊將日志打印到了標准輸出中,且只顯示了大於等於WARNING級別的日志,這說明默認的日志級別設置為WARNING(日志級別等級CRITICAL > ERROR > WARNING > INFO > DEBUG),默認的日志格式為日志級別:Logger名稱:用戶輸出消息。
靈活配置日志級別,日志格式,輸出位置:
import logging logging.basicConfig(level=logging.DEBUG, format='%(asctime)s %(filename)s[line:%(lineno)d] %(levelname)s %(message)s', datefmt='%a, %d %b %Y %H:%M:%S', filename='/tmp/test.log', filemode='w') logging.debug('debug message') logging.info('info message') logging.warning('warning message') logging.error('error message') logging.critical('critical message')
配置參數:

logging.basicConfig()函數中可通過具體參數來更改logging模塊默認行為,可用參數有: filename:用指定的文件名創建FiledHandler,這樣日志會被存儲在指定的文件中。 filemode:文件打開方式,在指定了filename時使用這個參數,默認值為“a”還可指定為“w”。 format:指定handler使用的日志顯示格式。 datefmt:指定日期時間格式。 level:設置rootlogger(后邊會講解具體概念)的日志級別 stream:用指定的stream創建StreamHandler。可以指定輸出到sys.stderr,sys.stdout或者文件(f=open(‘test.log’,’w’)),默認為sys.stderr。若同時列出了filename和stream兩個參數,則stream參數會被忽略。 format參數中可能用到的格式化串: %(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用戶輸出的消息
logger對象配置
import logging logger = logging.getLogger() # 創建一個handler,用於寫入日志文件 fh = logging.FileHandler('test.log') # 再創建一個handler,用於輸出到控制台 ch = logging.StreamHandler() formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') fh.setFormatter(formatter) ch.setFormatter(formatter) logger.addHandler(fh) #logger對象可以添加多個fh和ch對象 logger.addHandler(ch) logger.debug('logger debug message') logger.info('logger info message') logger.warning('logger warning message') logger.error('logger error message') logger.critical('logger critical message')
logging庫提供了多個組件:Logger、Handler、Filter、Formatter。Logger對象提供應用程序可直接使用的接口,Handler發送日志到適當的目的地,Filter提供了過濾日志信息的方法,Formatter指定日志顯示格式。另外,可以通過:logger.setLevel(logging.Debug)設置級別。
七 re模塊(正則表達式)★★★★★
就其本質而言,正則表達式(或 RE)是一種小型的、高度專業化的編程語言,(在Python中)它內嵌在Python中,並通過 re 模塊實現。正則表達式模式被編譯成一系列的字節碼,然后由用 C 編寫的匹配引擎執行。
常用正則表達式符號:
'.' 默認匹配除\n之外的任意一個字符,若指定flag DOTALL,則匹配任意字符,包括換行 '^' 匹配字符開頭,若指定flags MULTILINE,這種也可以匹配上(r"^a","\nabc\neee",flags=re.MULTILINE) '$' 匹配字符結尾,或e.search("foo$","bfoo\nsdfsf",flags=re.MULTILINE).group()也可以 '*' 匹配*號前的字符0次或多次,re.findall("ab*","cabb3abcbbac") 結果為['abb', 'ab', 'a'] '+' 匹配前一個字符1次或多次,re.findall("ab+","ab+cd+abb+bba") 結果['ab', 'abb'] '?' 匹配前一個字符1次或0次 '{m}' 匹配前一個字符m次 '{n,m}' 匹配前一個字符n到m次,re.findall("ab{1,3}","abb abc abbcbbb") 結果'abb', 'ab', 'abb'] '|' 匹配|左或|右的字符,re.search("abc|ABC","ABCBabcCD").group() 結果'ABC' '(...)' 分組匹配,re.search("(abc){2}a(123|456)c", "abcabca456c").group() 結果 abcabca456c '\A' 只從字符開頭匹配,re.search("\Aabc","alexabc") 是匹配不到的 '\Z' 匹配字符結尾,同$ '\d' 匹配數字0-9 '\D' 匹配非數字 '\w' 匹配[A-Za-z0-9] '\W' 匹配非[A-Za-z0-9] 's' 匹配空白字符、\t、\n、\r , re.search("\s+","ab\tc1\n3").group() 結果 '\t' '(?P<name>...)' 分組匹配 re.search("(?P<province>[0-9]{4})(?P<city>[0-9]{2})(?P<birthday>[0-9]{4})","371481199306143242").groupdict("city") 結果{'province': '3714', 'city': '81', 'birthday': '1993'}
最常用的匹配語法:
re.match 從頭開始匹配
re.search 匹配包含
re.findall 把所有匹配到的字符放到以列表中的元素返回
re.splitall 以匹配到的字符當做列表分隔符
re.sub 匹配字符並替換
re.split 按某種形式分割
re.
compile 建立匹配的規則,可以被調用
詳細如下:
import re #1 re.findall('a','alvin yuan') #返回所有滿足匹配條件的結果,放在列表里 #2 re.search('a','alvin yuan').group() #函數會在字符串內查找模式匹配,只到找到第一個匹配然后返回一個包含匹配信息的對象,該對象可以 # 通過調用group()方法得到匹配的字符串,如果字符串沒有匹配,則返回None。 #3 re.match('a','abc').group() #同search,不過盡在字符串開始處進行匹配 #4 ret=re.split('[ab]','abcd') #先按'a'分割得到''和'bcd',在對''和'bcd'分別按'b'分割 print(ret)#['', '', 'cd'] #5 ret=re.sub('\d','abc','alvin5yuan6',1) print(ret)#alvinabcyuan6 ret=re.subn('\d','abc','alvin5yuan6') print(ret)#('alvinabcyuanabc', 2) #6 obj=re.compile('\d{3}') ret=obj.search('abc123eeee') print(ret.group())#123
import re ret=re.finditer('\d','ds3sy4784a') print(ret) #<callable_iterator object at 0x10195f940> print(next(ret).group()) print(next(ret).group())
注意:
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']
補充:

import re print(re.findall("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")) print(re.search("<(?P<tag_name>\w+)>\w+</(?P=tag_name)>","<h1>hello</h1>")) print(re.search(r"<(\w+)>\w+</\1>","<h1>hello</h1>"))

#匹配出所有的整數 import re #ret=re.findall(r"\d+{0}]","1-2*(60+(-40.35/5)-(-4*3))") ret=re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))") ret.remove("") print(ret)
元字符之轉義符\
反斜杠后邊跟元字符去除特殊功能,比如\.
反斜杠后邊跟普通字符實現特殊功能,比如\d
\d 匹配任何十進制數;它相當於類 [0-9]。 \D 匹配任何非數字字符;它相當於類 [^0-9]。 \s 匹配任何空白字符;它相當於類 [ \t\n\r\f\v]。 \S 匹配任何非空白字符;它相當於類 [^ \t\n\r\f\v]。 \w 匹配任何字母數字字符;它相當於類 [a-zA-Z0-9_]。 \W 匹配任何非字母數字字符;它相當於類 [^a-zA-Z0-9_] \b 匹配一個特殊字符邊界,比如空格 ,&,#等
ret=re.findall('I\b','I am LIST') print(ret)#[] ret=re.findall(r'I\b','I am LIST') print(ret)#['I']
看下面兩個匹配:
#-----------------------------eg1: import re ret=re.findall('c\l','abc\le') print(ret)#[] ret=re.findall('c\\l','abc\le') print(ret)#[] ret=re.findall('c\\\\l','abc\le') print(ret)#['c\\l'] ret=re.findall(r'c\\l','abc\le') print(ret)#['c\\l'] #-----------------------------eg2: #之所以選擇\b是因為\b在ASCII表中是有意義的 m = re.findall('\bblow', 'blow') print(m) m = re.findall(r'\bblow', 'blow') print(m)
元字符之分組()
m = re.findall(r'(ad)+', 'add') print(m) ret=re.search('(?P<id>\d{2})/(?P<name>\w{3})','23/com') print(ret.group())#23/com print(ret.group('id'))#23
元字符之|
ret=re.search('(ab)|\d','rabhdg8sd') print(ret.group())#ab
筆記:

# 正則:對字符串的模糊匹配 # key:元字符(有特殊功能的字符) import re # re.findall(pattern, string,) # 找到所有的匹配元素,返回列表 #元字符介紹 # . :匹配除\n以外的任意符號 #print(re.findall("a.+d","abcd")) # ^:從字符串開始位置匹配 # $:從字符串結尾匹配 # print(re.findall("^yuan","yuandashj342jhg234")) # print(re.findall("yuan$","yuandashj342jhg234yuan")) # * + ? {} :重復 #print(re.findall("[0-9]{4}","af5324jh523hgj34gkhg53453")) #貪婪匹配 print(re.findall("\d+","af5324jh523hgj34gkhg53453")) #非貪婪匹配 # print(re.findall("\d+?","af5324jh523hgj34gkhg53453")) # print(re.findall("(abc\d)*?","af5324jh523hgj34gkhg53453")) # 字符集 []: 起一個或者的意思 # print(re.findall("a[bc]d","hasdabdjhacd")) #注意: * ,+.等元字符都是普通符號, - ^ \ # print(re.findall("[0-9]+","dashj342jhg234")) # print(re.findall("[a-z]+","dashj342jhg234")) # # print(re.findall("[^\d]+","d2a2fhj87fgj")) # ():分組 # print(re.findall("(ad)+","addd")) # print(re.findall("(ad)+yuan","adddyuangfsdui")) # print(re.findall("(?:ad)+yuan","adadyuangfsdui")) # print(re.findall("(?:\d)+yuan","adad678423yuang4234fsdui")) #命名分組 #ret8=re.search(r"(?P<A>\w+)\\aticles\\(?P<id>\d{4})",r"yuan\aticles\1234") #ret8=re.search(r"a\\nb",r"a\nb") #print(ret8) # print(ret8.group("id")) # print(ret8.group("A")) # # | :或 # # print(re.findall("www\.(?:oldboy|baidu)\.com","www.oldboy.com")) # \:轉義 # 1 后面加一個元字符使其變成普通符號 \. \* # 2 將一些普通符號變成特殊符號 比如 \d \w # print(re.findall("\d+\.?\d*\*\d+\.?\d*","-2*6+7*45+1.456*3-8/4")) # print(re.findall("\w","$da@s4 234")) # print(re.findall("a\sb","a badf")) # print(re.findall("\\bI","hello I am LIA")) # print(re.findall(r"\dI","hello 654I am LIA")) # print(re.findall(r"c\\l","abc\l")) # re的方法 # re.findall() # s=re.finditer("\d+","ad324das32") # print(s) # # print(next(s).group()) # print(next(s).group()) # "(3+7*2+27+7+(4/2+1))+3" # search;只匹配第一個結果 # ret=re.search("\d+","djksf34asd3") # print(ret.group()) # # #match:只在字符串開始的位置匹配 # ret=re.match("\d+","423djksf34asd3") # print(ret.group()) #split 分割 # s2=re.split("\d+","fhd3245jskf54skf453sd",2) # print(s2) # # ret3=re.split("l","hello yuan") # print(ret3) # # #sub: 替換 # # ret4=re.sub("\d+","A","hello 234jkhh23",1) # print(ret4) # # ret4=re.subn("\d+","A","hello 234jkhh23") # print(ret4) #compile: 編譯方法 # c=re.compile("\d+") # # ret5=c.findall("hello32world53") #== re.findall("\d+","hello32world53") # print(ret5) #計算:"1 - 2 * ( (60-30*2+-96) - (-4*3)/ (16-3*2) )" # s1="1+-2++5" # # def addsub(s): # pass # # def muldiv(s): #(60-30*2+-96) # pass # return (60-60+-96) # # def f(s): # s.replace("+-","-") # # # while re.search("\([^()]+\)", s): # res = re.search("\([^()]+\)", s) #(60-30*2+-96) # res=muldiv(res) # ret=addsub(res) # else: # res = muldiv(res) # ret = addsub(res) s="2" print(res.group())
插一嘴:注意下ASCII表中一些反斜杠的特殊意義!
八 json&pickle模塊(序列化模塊)★★★★
之前我們學習過用eval內置方法可以將一個字符串轉成python對象,不過,eval方法是有局限性的,對於普通的數據類型,json.loads和eval都能用,但遇到特殊類型的時候,eval就不管用了,所以eval的重點還是通常用來執行一個字符串表達式,並返回表達式的值。

#---轉換類型 d={"name":"yuan"} s=str(d) print(type(s)) d2=eval(s) print(d2[1]) with open("test") as f: for i in f : if type(eval(i.strip()))==dict: print(eval(i.strip())[1]) # 計算 print(eval("12*7+5-3"))
什么是序列化:
我們把對象(變量)從內存中變成可存儲或傳輸的過程稱之為序列化,在Python中叫pickling,在其他語言中也被稱之為serialization,marshalling,flattening等等,都是一個意思。序列化之后,就可以把序列化后的內容寫入磁盤,或者通過網絡傳輸到別的機器上。反過來,把變量內容從序列化的對象重新讀到內存里稱之為反序列化,即unpickling。
強調注意:damps、damp、loads,這3個用法要掌握,在json和pickle中3者都是一樣的用法。
json
如果我們要在不同的編程語言之間傳遞對象,就必須把對象序列化為標准格式,比如XML,但更好的方法是序列化為JSON,因為JSON表示出來就是一個字符串,可以被所有語言讀取,也可以方便地存儲到磁盤或者通過網絡傳輸。JSON不僅是標准格式,並且比XML更快,而且可以直接在Web頁面中讀取,非常方便。
JSON表示的對象就是標准的JavaScript語言的對象一個子集,JSON和Python內置的數據類型對應如下:

import json i=10 s='hello' t=(1,4,6) l=[3,5,7] d={'name':"yuan"} json_str1=json.dumps(i) json_str2=json.dumps(s) json_str3=json.dumps(t) json_str4=json.dumps(l) json_str5=json.dumps(d) print(json_str1) #'10' print(json_str2) #'"hello"' print(json_str3) #'[1, 4, 6]' print(json_str4) #'[3, 5, 7]' print(json_str5) #'{"name": "yuan"}'
python在文本中的使用:
#----------------------------序列化 import json dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#<class 'dict'> data=json.dumps(dic) print("type",type(data))#<class 'str'> print("data",data) f=open('序列化對象','w') f.write(data) #-------------------等價於json.dump(dic,f) f.close() #-----------------------------反序列化<br> import json f=open('序列化對象') new_data=json.loads(f.read())# 等價於data=json.load(f) print(type(new_data))
import json i=10 s='hello' t=(1,4,6) l=[3,5,7] d={'name':"yuan"} json_str1=json.dumps(i) json_str2=json.dumps(s) json_str3=json.dumps(t) json_str4=json.dumps(l) json_str5=json.dumps(d) print(json_str1) #'10' print(json_str2) #'"hello"' print(json_str3) #'[1, 4, 6]' print(json_str4) #'[3, 5, 7]' print(json_str5) #'{"name": "yuan"}'
d={"河北":["廊坊","保定"],"湖南":["長沙","韶山"]} d={'name':"egon"} s=json.dumps(d) # 將字典d轉為json字符串---序列化 print(type(s)) print(s) f=open("new",'w') f.write(s) f.close() # -------------- dump方式 f=open("new2",'w') json.dump(d,f)#---------1 轉成json字符串 2 將json字符串寫入f里 f.close() #-----------------反序列化 f=open("new") data=f.read() data2=json.loads(data) print(data2["name"]) #------練習 f=open("new3") data=f.read() ret=json.loads(data) # ret=[123] print(type(ret[0]))
pickle
##----------------------------序列化 import pickle dic={'name':'alvin','age':23,'sex':'male'} print(type(dic))#<class 'dict'> j=pickle.dumps(dic) print(type(j))#<class 'bytes'> f=open('序列化對象_pickle','wb')#注意是w是寫入str,wb是寫入bytes,j是'bytes' f.write(j) #-------------------等價於pickle.dump(dic,f) f.close() #-------------------------反序列化 import pickle f=open('序列化對象_pickle','rb') data=pickle.loads(f.read())# 等價於data=pickle.load(f) print(data['age'])
import pickle import datetime t=datetime.datetime.now() d={"data":t} json.dump(d,open("new4","w")) d={"name":"alvin"} s=pickle.dumps(d) print(s) print(type(s)) f=open('new5',"wb") f.write(s) f.close() f=open("new5","rb") data=pickle.loads(f.read()) print(data)
九 xml模塊★★
十 configparser模塊★★
十一 shutil模塊
十二 requests模塊
請看這里詳解:http://www.cnblogs.com/wangyongsong/p/7445322.html#_label0
使用Python的Requests庫進行web接口測試:http://blog.csdn.net/liuchunming033/article/details/45538205
十三 paramiko
十四 shelve模塊★★★
十五 subprocess模塊★★★★
常用subprocess方法示例:
#執行命令,返回命令執行狀態 , 0 or 非0 >>> retcode = subprocess.call(["ls", "-l"]) #執行命令,如果命令結果為0,就正常返回,否則拋異常 >>> subprocess.check_call(["ls", "-l"]) 0 #接收字符串格式命令,返回元組形式,第1個元素是執行狀態,第2個是命令結果 >>> subprocess.getstatusoutput('ls /bin/ls') (0, '/bin/ls') #接收字符串格式命令,並返回結果 >>> subprocess.getoutput('ls /bin/ls') '/bin/ls' #執行命令,並返回結果,注意是返回結果,不是打印,下例結果返回給res >>> res=subprocess.check_output(['ls','-l']) >>> res b'total 0\ndrwxr-xr-x 12 alex staff 408 Nov 2 11:05 OldBoyCRM\n' #上面那些方法,底層都是封裝的subprocess.Popen poll() Check if child process has terminated. Returns returncode wait() Wait for child process to terminate. Returns returncode attribute. terminate() 殺掉所啟動進程 communicate() 等待任務結束 stdin 標准輸入 stdout 標准輸出 stderr 標准錯誤 pid The process ID of the child process. #例子 >>> p = subprocess.Popen("df -h|grep disk",stdin=subprocess.PIPE,stdout=subprocess.PIPE,shell=True) >>> p.stdout.read() b'/dev/disk1 465Gi 64Gi 400Gi 14% 16901472 104938142 14% /\n'
筆記例子:

1 import subprocess 2 3 subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE,stderr=subprocess) 4 #執行這個命令得是字符串格式,因此'dir'是字符串格式 #stdout 標准輸出內容 #stderr 出錯的內容 5 #PIPE 管道,將管道左邊的內容丟入管道,管道右邊從管道內去拿 6 7 8 res=subprocess.Popen('dir',shell=True,stdout=subprocess.PIPE) 9 print(res) 10 11 res.stdout.read() #將管道內的標准內容讀取出來,並且讀出來的編碼格式是bash,是以當前操作系統的編碼格式而定的 12 res.stderr.read() #將管道內的錯誤內容讀取出來,並且讀出來的編碼格式是bash,是以當前操作系統的編碼格式而定的 13 14 data=res.stdout.read() 15 data.decode('GBK') #讀出內容是什么格式就用什么格式解碼
>>> subprocess.run(["ls", "-l"]) # doesn't capture output CompletedProcess(args=['ls', '-l'], returncode=0) >>> subprocess.run("exit 1", shell=True, check=True) Traceback (most recent call last): ... subprocess.CalledProcessError: Command 'exit 1' returned non-zero exit status 1 >>> subprocess.run(["ls", "-l", "/dev/null"], stdout=subprocess.PIPE) CompletedProcess(args=['ls', '-l', '/dev/null'], returncode=0, stdout=b'crw-rw-rw- 1 root root 1, 3 Jan 23 16:23 /dev/null\n')
調用subprocess.run(...)是推薦的常用方法,在大多數情況下能滿足需求,但如果你可能需要進行一些復雜的與系統的交互的話,你還可以用subprocess.Popen(),語法如下:
p = subprocess.Popen("find / -size +1000000 -exec ls -shl {} \;",shell=True,stdout=subprocess.PIPE) print(p.stdout.read())