這一部分是python內置模塊系列的最後一部分,介紹了一些小巧有用的內置模塊。
目錄:
random模塊是python提供的生成偽隨機數模塊,使用很簡單,如下的三個方法都是生成1個隨機數:
import random print(random.random()) print(random.randint(1, 2)) print(random.randrange(1, 10))
還有一些方法比較有意思,比如seed和choice。
import random alist = [1, 2, 3, 4, 5, 6, 7, 8, 9] t = random.choice(alist) print(t) 運行結果: 程序會在alist裡面隨機選擇一個數。
下面是生成一個包含大寫字母A-Z和數字0-9的隨機驗證碼的程序
import random
checkcode = ''
for i in range(4):
current = random.randrange(0,4)
if current != i:
temp = chr(random.randint(65,90))
else:
temp = random.randint(0,9)
checkcode += str(temp)
print(checkcode)
shelve模塊是一個簡單的k,v鍵值對,將內存數據通過文件持久化的模塊,可以持久化任何pickle可支持的python數據格式。
它只有一個open和一個close方法,與python的內置文件處理方法很像。
import shelve
d = shelve.open('shelve_test') #打開一個文件
class Test(object):
def __init__(self,n):
self.n = n
t = Test(123)
t2 = Test(123334)
name = ["alex","rain","test"]
d["test"] = name #持久化列表
d["t1"] = t #持久化類
d["t2"] = t2
d.close()
唯一需要注意的是,通過open獲得的內容讀入內存後,所進行的修改在close之前不會保存到文件中,因此看下面的代碼:
import shelve
s = shelve.open("testfile")
s["key"] = ['a', 'b', 'c']
print(s['key'])
s['key'].append('d')
print(s['key'])
運行結果:
['a', 'b', 'c']
['a', 'b', 'c']
“d”並沒有被添加到列表的裡面。怎麼解決這個問題?使用一個臨時變量!
import shelve
s = shelve.open("testfile")
s["key"] = ['a', 'b', 'c']
print(s["key"])
tmp = s["key"]
tmp.append('d')
s["key"] = tmp
print(s["key"])
運行結果:
['a', 'b', 'c']
['a', 'b', 'c', 'd']
getpass模塊非常簡單,它能夠讓你在輸入密碼的時候不會在屏幕上顯示密碼,安全性更高。注意:在pycharm環境裡這個模塊用不了!
getpass模塊只有2個常用方法:getpass和getuser。參考下面的例子:
import getpass
pwd = getpass.getpass("請輸入密碼: ") # 可代替input方法,接收用戶輸入的密碼
print(getpass.getuser()) # getuser方法會返回當前執行程序的用戶名
當你需要壓縮文件的時候,使用這個模塊會比較方便。
import zipfile
# 壓縮
z = zipfile.ZipFile('laxi.zip', 'w')
z.write('a.log')
z.write('data.data') # 可以一個一個添加文件進壓縮包
z.close()
# 解壓
z = zipfile.ZipFile('laxi.zip', 'r')
z.extractall() # 這是一次性將壓縮包內的文件全部解壓出來
z.close()
要單獨解壓壓縮包內的某個文件就需要先獲得壓縮包內的文件名列表。zipfile提供了一個namelist方法。
import zipfile
z = zipfile.ZipFile('laxi.zip', 'r')
ret = z.namelist()
print(ret)
z.close()
運行結果:
['testfile.bak', 'testfile.dat']
然後通過具體的文件名去解壓某個文件。zipfile提供了extract方法。
import zipfile
z = zipfile.ZipFile('laxi.zip', 'r')
z.extract("testfile.bak")
z.close()
當你需要對文件進行打包的時候,這個模塊比較方便。一般的用法如下:
import tarfile
# 壓縮
tar = tarfile.open('your.tar','w')
tar.add('/Users/wupeiqi/PycharmProjects/bbs2.log', arcname='bbs2.log')
tar.add('/Users/wupeiqi/PycharmProjects/cmdb.log', arcname='cmdb.log')
tar.close()
# 解壓
tar = tarfile.open('your.tar','r')
tar.extractall() # 可設置解壓地址
tar.close()
tarfile解壓縮
注意和zipfile的區別,在實例對象的時候用的是open方法,而不是類似“zipfile”的方法。其它用法基本類似。
如果要解包單獨的文件,請先用getmembers方法獲取包內的文件名,然後使用extract方法解包指定的文件,類似上面的zipfile模塊。
這是一個python內置的二分查找法模塊,其源碼短得可憐。

"""Bisection algorithms."""
def insort_right(a, x, lo=0, hi=None):
"""Insert item x in list a, and keep it sorted assuming a is sorted.
If x is already in a, insert it to the right of the rightmost x.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
"""
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if x < a[mid]: hi = mid
else: lo = mid+1
a.insert(lo, x)
insort = insort_right # backward compatibility
def bisect_right(a, x, lo=0, hi=None):
"""Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e <= x, and all e in
a[i:] have e > x. So if x already appears in the list, a.insert(x) will
insert just after the rightmost x already there.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
"""
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if x < a[mid]: hi = mid
else: lo = mid+1
return lo
bisect = bisect_right # backward compatibility
def insort_left(a, x, lo=0, hi=None):
"""Insert item x in list a, and keep it sorted assuming a is sorted.
If x is already in a, insert it to the left of the leftmost x.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
"""
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if a[mid] < x: lo = mid+1
else: hi = mid
a.insert(lo, x)
def bisect_left(a, x, lo=0, hi=None):
"""Return the index where to insert item x in list a, assuming a is sorted.
The return value i is such that all e in a[:i] have e < x, and all e in
a[i:] have e >= x. So if x already appears in the list, a.insert(x) will
insert just before the leftmost x already there.
Optional args lo (default 0) and hi (default len(a)) bound the
slice of a to be searched.
"""
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi)//2
if a[mid] < x: lo = mid+1
else: hi = mid
return lo
# Overwrite above definitions with a fast C implementation
try:
from _bisect import *
except ImportError:
pass
bisect源碼
模塊內只有4個方法:bisect_right、bisect_left、insort_right和insort_left。然後通過將bisect_right賦值給bisect,將insort_right賦值給insort實現向後兼容。實際使用中,是需要記住bisect和insort兩個方法即可。
bisect模塊的使用方法通常是:bisect.bisect(list,x),其中x表示要查找的值,list是一個默認已經排好序的列表。
bisect():返回值是x在列表中應處的位置下標,並不修改列表本身。
import bisect
x = 200
list1 = [1, 3, 6, 24, 55, 78, 454, 555, 1234, 6900]
ret = bisect.bisect(list1, x)
print("返回值: ", ret)
print("list1 = ", list1)
運行結果:
返回值: 6
list1 = [1, 3, 6, 24, 55, 78, 454, 555, 1234, 6900]
insort():返回值是將x插入到列表中後的新列表。x插在它的大小排序所在位置。
import bisect
x = 200
list1 = [1, 3, 6, 24, 55, 78, 454, 555, 1234, 6900]
ret = bisect.insort(list1, x)
print("返回值: ", ret)
print("list1 = ", list1)
運行結果:
返回值: None
list1 = [1, 3, 6, 24, 55, 78, 200, 454, 555, 1234, 6900]
使用過python內置的open方法處理文件的同學都知道,它沒有直接修改文件內容的方法。這個fileinput可以幫助我們輕松的實現文件內容的修改功能。fileinput模塊中的重要方法如下:
最重要的方法,用於遍歷打開的文件,inplace為True的時候,會將修改寫入文件,backup為True的時候會進行備份操作。
返回當前文件的名字
返回當前(累計)的行數。同時處理多個文件時,行數會累計。
返回當前文件的總行數。處理新文件時,行數會重置為1,重新計數。
檢查當前行是否是文件的第一行
檢查最後一行是否來自sys.stdin
關閉當前文件,移動到下一個文件(fileinput是可以同時處理多個文件的!)
關閉整個文件鏈,結束迭代。
為了演示fileinput的使用,假設編寫了如下的一個腳本,想要為其代碼進行編號。為了讓腳本在進行代碼編號後仍然能夠正常運行,我們只能在每一行的右側加上#來注釋行號。其中,我們假定每個代碼行最多有40個字符。具體代碼如下:
import fileinput
f = fileinput.input(inplace=True)
for line in f:
line = line.rstrip()
num = fileinput.lineno()
print("%-40s # %2i" % (line, num))
f.close()
注意,只能使用rstrip,不能直接用strip,那樣會把左邊的縮進也給去掉了。
請在終端環境下,使用python fileinput_test.py fileinput_test.py的方式執行程序,結果如下:
import fileinput # 1
# 2
f = fileinput.input(inplace=True) # 3
for line in f: # 4
line = line.rstrip() # 5
num = fileinput.lineno() # 6
print("%-40s # %2i" % (line, num)) # 7
f.close() # 8
要小心使用inplace參數,它會修改文件。應該在不適用inplace設置的情況下仔細測試自己的程序(這樣只會打印出結果),在確保程序工作正常後再修改文件。