前言
《編寫高質(zhì)量python代碼的59個有效方法》這本書分類逐條地介紹了編寫python代碼的有效思路和方法,對理解python和提高編程效率有一定的幫助。本筆記簡要整理其中的重要方法。
承接上文http://www.itdecent.cn/p/15a6050220e6
http://www.itdecent.cn/p/1f6a2b3b502e
元類與屬性 http://www.itdecent.cn/p/1b1f3a0e87aa
并發(fā)及并行:http://www.itdecent.cn/p/60ad9066d4b6
本篇介紹內(nèi)置模塊
6. 內(nèi)置模塊
用functools.wraps定義函數(shù)修飾器
Python用特殊的語法來表示修飾器,可以用來修飾函數(shù),對于受到封裝的原函數(shù)來說,修飾器能夠在原函數(shù)執(zhí)行之前及執(zhí)行完畢之后,分別運(yùn)行一些附加代碼,使得開發(fā)者可以在修飾器中訪問并修改原函數(shù)的參數(shù)及返回值,輔助調(diào)試等。
如下例,在遞歸函數(shù)中,利用修飾器trace將每次輸入和輸出打印出來:
def trace(func):
def wrapper(*args,**kwargs):
result=func(*args,**kwargs) # 執(zhí)行原函數(shù)
print('%s(%r,%r)->%r'%(func.__name__,args,kwargs,result)) # 打印我們要的信息
return result # 返回原函數(shù)的結(jié)果
return wrapper
@trace
def fibonacci(n):
if n in (0,1):
return n
return (fibonacci(n-2)+fibonacci(n-1))
# output
#fibonacci((0,),{})->0
#fibonacci((1,),{})->1
#fibonacci((2,),{})->1
但是加了修飾器后,原函數(shù)的一些特性在調(diào)用時發(fā)生改變:函數(shù)名稱與原來名稱不同,變成了修飾器內(nèi)部函數(shù)的名稱

使用functools中定義的wraps來對修飾器進(jìn)行修飾即可,可以保證原函數(shù)的重要元數(shù)據(jù)都能被外界訪問到:
from functools import wraps
def trace(func):
@wraps
def wrapper(*args,**kwargs):
result=func(*args,**kwargs)
print('%s(%r,%r)->%r'%(func.__name__,args,kwargs,result))
return result
return wrapper
@trace
def fibonacci(n):
if n in (0,1):
return n
return (fibonacci(n-2)+fibonacci(n-1))
使用contextlib 和 with 語句改寫可復(fù)用的try/finally代碼
from threading import Lock
lock=Lock()
with lock:
print('Hold the lock')
lock.acquire()
try:
print('lock is held')
finally:
lock.release()
Python提供了with語句來表達(dá)代碼的運(yùn)行時機(jī)。如上例所示,可以使用with的方式來進(jìn)行操作,替代try/finally結(jié)構(gòu)的代碼。
我們可以使用內(nèi)置的contextlib模塊中的contextmanager修飾器,使用其修飾自己的函數(shù),使得該函數(shù)支持with語句


使用datetime模塊出來本地時間,而非time模塊
UTC時間是一種標(biāo)準(zhǔn)的時間表示方式,與時區(qū)無關(guān)。對于計算機(jī)而言,UTC是一種非常好的計時方式,對人卻不合適。需要將UTC和當(dāng)?shù)貢r間進(jìn)行有效轉(zhuǎn)換。
time模塊中可以將UTC跟當(dāng)?shù)貢r間進(jìn)行轉(zhuǎn)換
from time import time,localtime,strftime,strptime,mktime
### 將時間戳轉(zhuǎn)換成為字符串表示
now=time()
local=localtime(now)
time_str=strftime('%Y-%m-%d %H:%M:%S',local)
print(time_str) # 2020-09-16 19:59:34
time_tuple=strptime(time_str,'%Y-%m-%d %H:%M:%S')
utc_now=mktime(time_tuple)
print(utc_now) #1600257574.0
其中strftime、strptime可以實(shí)現(xiàn)將時間從時間戳轉(zhuǎn)為標(biāo)準(zhǔn)格式的字符串或者反過來轉(zhuǎn)為時間對象。這樣地轉(zhuǎn)換依賴于操作系統(tǒng)的時取配置信息,直接轉(zhuǎn)為本地時取的時間信息。
datetime模塊功能更加全面,可以轉(zhuǎn)換成其他時區(qū)的時間
from datetime import datetime,timezone
now=datetime(2014,8,10,18,18,30)
now_utc=now.replace(tzinfo=timezone.utc)
now_local=now_utc.astimezone()
print(now_local)
同時datetime還具有timedelta等更由實(shí)用價值的時間計算工具,在編程中要多多使用。
使用內(nèi)置算法與數(shù)據(jù)結(jié)構(gòu)
python標(biāo)準(zhǔn)庫中通用內(nèi)置了大量數(shù)據(jù)結(jié)構(gòu)和算法,不僅執(zhí)行速度高,還能簡化編程。
- 雙向隊列:deque 能夠從隊列頭部/尾部插入或移除一個元素,只需消耗常數(shù)級別的時間。非常適合表示FIFO先進(jìn)先出的隊列
from collections import deque
fifo=deque()
fifo.append(1)
x=fifo.popleft()
fifo.appendleft(1)
fifo.appendleft(2)
y=fifo.pop()
list數(shù)據(jù)類型,當(dāng)從頭部插入或者移除元素時會消耗線性級別的時間,比較慢。
- 有序字典 OrderedDict
默認(rèn)的字典是無序的,當(dāng)在鍵值相同的兩個dict上迭代時,可能會出現(xiàn)不同的迭代順序,主要是由于快速哈希表引起的。
from collections import OrderedDict
a= OrderedDict()
a['1']=1
a['2']=3
a['0']=0
# (OrderedDict([('1', 1), ('2', 3), ('0', 0)])
OrderedDict可以根據(jù)鍵的插入順序,保留鍵值對在字典中的次序。
3. 帶有默認(rèn)值的字典
states={}
key='test'
if key not in states:
states[key]=0
states[key]+=1
當(dāng)我們用字典保存計數(shù)器信息時,需要如上的寫法。我們可以用下面setdefault這種形式代替手工的查詢判斷。
states={}
key='test'
states.setdefault(key,0)
states[key]+=1
print(states)
key='test'
states.setdefault(key,0)
states[key]+=1
print(states)
也可使用defaultdict來簡化
from collections import defaultdict
states=defaultdict(int)
key='test'
states[key]+=1
堆隊列 headq
堆適合實(shí)現(xiàn)優(yōu)先級隊列,heaqp提供了heappush、heappop和nsmallest等一些函數(shù),能夠在標(biāo)準(zhǔn)的list類型之中創(chuàng)建堆結(jié)構(gòu)。
首先定義一個list,heappush可以將數(shù)據(jù)加入堆中,將list轉(zhuǎn)換為堆結(jié)構(gòu);heappop能夠每次從推中取出最小值。
from heapq import heappush,heappop
a=[]
heappush(a,5)
heappush(a,3)
heappush(a,7)
heappush(a,4)
print(heappop(a),heappop(a))
二分查找
from bisect import bisect_left
x=list(range(10*5))
i=x.index(100)
i=bisect_left(x,100)
print(i)
bisect模塊中提供二分搜索方式,比線性的搜索算法更快。
6. 迭代器相關(guān) itertools
itertools中提供大量函數(shù),可以組合并操控迭代器,詳細(xì)請自己查找相關(guān)資料
END
本人簡書所有文章均為原創(chuàng),歡迎轉(zhuǎn)載,請注明文章出處 。百度和CSDN等站皆不可信,搜索請謹(jǐn)慎鑒別。技術(shù)類文章一般都有時效性,本人習(xí)慣不定期對自己的筆記/博文進(jìn)行更新,因此請訪問本人簡書主頁查看最新信息http://www.itdecent.cn/u/40d14973d97c