random模塊用於獲取隨機數,一下random模塊中經常使用的函數:python
# 返回 (0,1) ,float類型 random.random() # 返回 [1,3],int 類型 random.randint(1, 3) # 返回 [1,3),int 類型 random.randrange(1, 3) # 隨機獲取列表中的一個元素 random.choice([3,4,5,2,1, 'kitty']) # 隨機獲取列表中的2個元素,以列表的形式返回 random.sample([3,4,5,2,1, 'kitty'], 2) # 返回[1,3],float類型 random.uniform(1,3) # 隨機打亂 類表lst 中的元素順序 lst = [111,222,333,444] random.shuffle(lst)
示例(隨機獲取驗證碼),5位驗證碼,包含整數,大小寫字母~算法
def valdate_code(): res = '' for i in range(5): num = random.randint(0, 9) alpha_lower = chr(random.randint(97, 122)) # 小寫字母 alpha_upper = chr(random.randint(65, 90)) # 大寫字母 s = random.choice([str(num), alpha_lower, alpha_upper]) res += s return res 調用結果: 8Rj0x 306GX ...
hashlib模塊提供了常見的摘要算法,如MD5,SHA1等。
摘要算法是指 經過一個函數,將任意長度的數據轉換爲一個固定長度的字符串,一般用16進制的字符串表示~shell
import hashlib md5_obj = hashlib.md5() md5_obj.update(b"hello world") print(md5_obj.hexdigest()) # 5eb63bbbe01eeed093cb22bb8f5acdc3 # 如今對hello world改變一個字母 md5_obj.update(b"hello World") print(md5_obj.hexdigest()) # 4245dd40eaf3111caa3c8f9e3ceeed3c
數據由 'hello world' 改爲 'hello World',獲取的摘要信息徹底不相同。因此摘要算法通常用於提取數據的特徵碼。數據庫
摘要函數是一個單向函數,經過數據計算出其特徵碼很容易,可是要根據特徵碼反推出數據卻很困難。經過從數據中提取出的特徵碼能夠判斷數據是否被篡改過~安全
若如今要獲取一個大文件的特徵碼,能夠每讀取一行,對這一行的數據進行一次update(),到最後再進行特徵碼的計算,示例以下:bash
import hashlib md5_obj = hashlib.md5() with open(file='/Users/luyi/tmp/passwd', mode='r', encoding='utf-8') as f: for line in f: md5_obj.update(line.encode('utf-8')) print(md5_obj.hexdigest())
Tip:在python3中,傳遞給update的參數必須是 bytes 類型。python3中字符串默認使用 unicode 形式保存在內存中,須要將 unicode 形式的字符串 encode 爲 bytes 類型再進行操做~dom
上述示例中使用的摘要算法都是md5,md5是常見的摘要算法,生成速度快,生成的結果是一個固定的128 bit字節,一般用一個32位的16進制字符串表示。除了md5還有一種摘要算法sha1,調用sha1的方式與調用md5相似,sha1的結果是160 bit字節,一般用一個40位的16進制字符串表示。ide
import hashlib sha1_obj = hashlib.sha1() sha1_obj.update(b'hello world') sha1_obj.update(b'hello kitty') print(sha1_obj.hexdigest()) # 563258876190465d493543b96306a92164ac7e62
除了md5,sha1算法,還有 sha256 和 sha512,這兩個摘要算法獲取的摘要長度更長,更安全,可是計算的速度會更慢~函數
獲取數據的特徵碼,數據的長度是任意的,可是獲取的特徵碼(摘要信息)的長度是固定的,那就有可能出現這種狀況,兩個不同的數據,提取的特徵碼是一致的,這種狀況稱爲碰撞,只是發生的機率不大~測試
摘要算法還一般用於密碼的保存,密碼先進行單向加密後,而後再保存到數據庫中。當須要驗證密碼時,將用戶輸入的密碼也進行單向加密,而後和數據庫中存儲的進行比對~
可是這樣就又有一個問題,若用戶設置的密碼過於簡單,例如不少人會使用 '123456','admin','password'這樣的密碼,若公司存放用戶信息的表丟失,嘿客能夠事先計算出這些簡單密碼的md5值,而後與表中加密後的密碼進行比對,這樣部分用戶的密碼就會被嘿客獲取。
e10adc3949ba59abbe56e057f20f883e 123456 21232f297a57a5a743894a0e4a801fc3 admin 5f4dcc3b5aa765d61d8327deb882cf99 password
解決的方法就是,對原始的密碼「加鹽操做」。即對原始的密碼再加上其特有的字符串,例如將用戶的密碼再加上其用戶名,而後再進行單項加密操做~,這樣即便用戶使用的密碼相同,加上用戶名後獲取的摘要信息也不會相同~
import hashlib md5_obj = hashlib.md5(b'kitty') # 在這裏進行加鹽 md5_obj.update(b"123456") print(md5_obj.hexdigest())
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") # 重命名文件/目錄,注意若文件未打開狀態,則沒法rename 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的大小
常常會使用的就以下幾個:
os.remove() os.path.abspath(path) os.path.abspath(__file__) # 獲取當前執行腳本的路徑 os.path.dirname(path) os.path.basename(path) os.path.exists(path) os.path.isfile(path) os.path.isdir(path) os.path.join(path1[, path2[, ...]]) os.path.join('/','etc', 'passwd') # /etc/passwd os.path.getsize(path) os.path.getsize('/etc/passwd') # 6804,單位字節
os.access() 用來檢測指定路徑的訪問權限~
語法:os.access(path, mode); - path:用來檢測的路徑,能夠是目錄,也能夠是文件~ - mode: - os.F_OK: 測試path是否存在。 - os.R_OK: 測試path是否可讀。 - os.W_OK: 測試path是否可寫。 - os.X_OK: 測試path是否可執行。
示例:
import os # 判斷目錄是否存在 res = os.access("/tmp", os.F_OK) print "F_OK - %s"% res # 判斷文件是否存在 res = os.access("/tmp/abc", os.F_OK) print "F_OK - %s"% res # 判斷目錄是否可讀 res = os.access("/tmp", os.R_OK) print "R_OK - %s"% res # 判斷文件是否可讀 res = os.access("/tmp/abc", os.R_OK) print "R_OK - %s"% res # 判斷文件是否可寫 res = os.access("/tmp/abc", os.W_OK) print "W_OK - %s"% res # 判斷文件是否可執行 res = os.access("/tmp/abc", os.X_OK) print "X_OK - %s"% res # 執行結果: F_OK - True F_OK - True R_OK - True R_OK - True W_OK - True X_OK - False
os 模塊是和操做系統交互的模塊,這裏的sys是和python解釋器交互的模塊
列出經常使用方法便可
sys經常使用的方法以下:
sys.argv # 命令行參數,以List形式返回,第一個元素是程序自己路徑 sys.exit(n) # 退出程序,正常退出是exit(0),參數爲返回碼 sys.version # 獲取Python解釋程序的版本信息 sys.maxint # 最大的Int值 sys.path # 返回模塊的搜索路徑,初始化時使用PYTHONPATH環境變量的值 sys.platform # 返回操做系統平臺名稱 sys.getdefaultencoding() # 獲取系統當前默認編碼,python2默認爲ascii,python3默認爲utf-8。 sys.setdefaultencoding() # python2中設置系統默認編碼,執行dir(sys)時不會看到這個方法,在解釋器中執行不經過,須要先執行reload(sys),再進行設置。python3中沒有此方法,也不能reload(sys)~ sys.getfilesystemencoding() # 獲取文件系統使用編碼方式,Windows下返回'mbcs',mac下返回'utf-8'. sys.stdin,sys.stdout,sys.stderr # stdin , stdout , 以及 stderr 變量包含與標準 I/O 流對應的流對象. 若是須要更好地控制輸出,而 print 不能知足要求, 可使用stdin , stdout , stderr 替換。這時候能夠重定向輸出或者輸入到其它設備( device ),或者以非標準的方式處理它們~
經過命令行運行Python程序時,命令行的執行文件 及參數會以列表的形式存放在 sys.argv 變量中~
sys_test.py文件內容以下: import sys print(sys.argv) 命令行執行: ➜ ~ python ~/tmp/sys_test.py 1 2 3 4 5 6 ['/Users/luyi/tmp/sys_test.py', '1', '2', '3', '4', '5', '6']
程序執行完成後,python解釋器自動退出,若因爲某些緣由須要在中途退出,可使用 sys.exit(n) ,參數n 可指定退出時的狀態碼,通常n=0表示正常退出,其餘數值(1-127)爲非正常退出~
示例:
# 執行以下內容的py文件 import sys sys.exit(2) ➜ tmp python sys_test.py ➜ tmp echo $? 2 # 狀態返回碼爲 2
程序的中途退出也可使用 SystemExit 進行捕獲,在 except 中完成退出以前必要的事項
print('start...') try: sys.exit(1) except SystemExit: print('end...') sys.exit(0) print('contimue') # 輸出結果: start... end...
sys.path 是一個列表,裏面存放的是模塊的搜索路徑。若須要使用的模塊不在這些路徑中,能夠直接將路徑添加到這個變量中,程序中的 import 就能正確導入該模塊~
>>> import sys >>> sys.path ['', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python36.zip', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload', '/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages']
當 python程序中涉及到 unicode類型 和 編碼的字符串 相互轉換時 (python2 中爲 str 類型 與 unicode類型相互轉換,python3中爲 str類型 和 bytes類型 之間的相互轉換,這一塊的詳細內容可參見 http://www.javashuo.com/article/p-mpawubgy-w.html ) 就會使用getdefaultencoding輸出的編碼進行轉換~
python2中默認編碼爲 ascii,python3中默認編碼爲 utf-8 ~
# python2 import sys print sys.getdefaultencoding() 輸出結果: ascii # python3 import sys print(sys.getdefaultencoding()) 輸出結果: utf-8
python3中,當str類型(python3中字符串一概使用unicode存放)和 bytes類型 合併時,會直接報錯:
x = '你好,' # str類型 y = '貝貝'.encode('utf-8') # bytes類型 print(x + y) 報錯信息: TypeError: must be str, not bytes
可是在python2中,這個過程能夠進行,Python解釋器會自動把 str 轉換成 unicode 再進行運算,運算結果也都是 unicode類型,在Python解釋器自動將 str 轉成 unicode時,因爲沒有具體指定使用哪一種編碼進行轉碼,因此python解釋器就會默認使用 getdefaultencoding中的編碼,python2中默認編碼是ascii,因而就出現以下錯誤:
x = u'你好,' y = '貝貝' print x + y 錯誤信息: UnicodeDecodeError: 'ascii' codec can't decode byte 0xe8 in position 0: ordinal not in range(128)
設置一下默認編碼,就能夠正常輸出:
# -*- coding: utf-8 -*- import sys reload(sys) sys.setdefaultencoding('utf-8') x = u'你好,' y = '貝貝' print x + y 輸出結果: 你好,貝貝
Tip:這個常常在 python2 中使用,python3中沒有這樣的操做,sys不能 reload,也沒有 setdefaultencoding 方法~,python3中默認編碼爲utf-8,也不須要修改~
.................^_^