1. 程式人生 > >python常用模塊(random,hashlib,os,sys)

python常用模塊(random,hashlib,os,sys)

替換 ref stat .py ror getmtime 系統交互 表示 模塊

random

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

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 模塊是與操作系統交互的一個接口
常用方法如下:

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,單位字節

sys

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 ),或者以非標準的方式處理它們~

sys.argv

通過命令行運行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‘]

sys.exit(n)

程序執行完成後,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

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‘]

sys.getdefaultencoding(),sys.setdefaultencoding()

當 python程序中涉及到 unicode類型 和 編碼的字符串 相互轉換時 (python2 中為 str 類型 與 unicode類型相互轉換,python3中為 str類型 和 bytes類型 之間的相互轉換,這一塊的詳細內容可參見 http://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,也不需要修改~

.................^_^

python常用模塊(random,hashlib,os,sys)