您好,登錄后才能下訂單哦!
random模塊用于獲取隨機數,一下random模塊中常用的函數:
# 返回 (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進制的字符串表示~
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(),到最后再進行特征碼的計算,示例如下:
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 類型再進行操作~
?
上述示例中使用的摘要算法都是md5,md5是常見的摘要算法,生成速度快,生成的結果是一個固定的128 bit字節,通常用一個32位的16進制字符串表示。除了md5還有一種摘要算法sha1,調用sha1的方式與調用md5類似,sha1的結果是160 bit字節,通常用一個40位的16進制字符串表示。
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(path2[, path3[, ...]]) # 將多個路徑組合后返回,第一個絕對路徑之前的參數將被忽略
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(path2[, path3[, ...]])
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類型 之間的相互轉換,這一塊的詳細內容可參見 https://blog.51cto.com/ljbaby/2164480 ) 就會使用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,也不需要修改~
.................^_^
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。