python基礎之裝飾器
阿新 • • 發佈:2018-11-10
裝飾器的本質是一個閉合函式,該閉合函式的自由變數是一個函式,可以使程式碼的重要性與擴充套件性大大加強。
通過@後新增裝飾器函式
能夠接收任何引數的通用引數裝飾器
# def checkParams(fn): # """只接受字串的裝飾器""" # def wrapper(strname): # if isinstance(strname,(str)):#判斷是否是字串型別 # return fn(strname)#如果是則呼叫fn(strname),返回計算結果 # print("Variable strname is not a string type") # return # return wrapper#將裝飾後的函式返回 def checkParams(fn): """能夠接收任何引數的通用引數裝飾器""" def wrapper(*arg,**kwargs):#使用字典和元組的解包引數來做形參 if isinstance(arg[0],(str)):#判斷第一個引數是否是字串 return fn(*arg,**kwargs) return return wrapper @checkParams def wrapperfun(strname): def recoder(age): print("姓名:",strname,"年紀:",age) return recoder fun=wrapperfun("Anna")#wrapperfun帶有引數檢查的閉合函式 fun(37)#為age賦值 fun=wrapperfun(546)#當輸入引數不合法時, fun(37)#沒有輸出顯示
可接收引數的通用裝飾器
def isadmin(userid): """可接收引數的通用裝飾器""" def checkPArams(fn): def wrapper(*arg,**kwargs):#定義一個檢查引數的函式 if userid!='admin':# print("Operation is prothibited as you are not admin!") return if isinstance(arg[0],(str)):#判斷是否是字串 return fn(*arg,**kwargs) print("variable strname is not a string type") return return wrapper#裝飾後的函式返回 return checkPArams @isadmin(userid="admin") def wrapperfun(strname): def recoder(age): print("姓名:",strname,"年紀:",age) return recoder @isadmin(userid="user") def wrapperfun2(strname): def recoder(age): print("姓名:",strname,"年紀:",age) return recoder fun=wrapperfun("Ana") fun(20) fun1=wrapperfun2("as") # fun1(37) fun2=wrapperfun2(123)
除了通過@加函式匯入裝飾器,還可以通過
wrapperfun=isadmin(userid="admin")(wrapperfun)
實現裝飾器匯入。
組合裝飾器
將不同的裝飾器使用@符號一行一行的疊堆起來
@isadmin(userid="admin")
@checkParams
裝飾器返回函式的名稱修復
當函式被裝飾完後,對函式的名字屬性再賦一次值,將函式的名稱恢復過來
# import functools def isadmin(userid): def checkParams(fn): # @functools.wraps(fn)#保證修飾後的函式與原函式的名稱一致 def wrapper(*arg,**kwargs): if userid!="admin": print("Operation is prohibited as you are not admin!") return if isinstance(arg[0],(str)): return fn(*arg,**kwargs) print("variable strname is not a string type") return wrapper.__name__=fn.__name__#將函式名稱屬性恢復,或者通過#@functools.wraps(fn)實現 return wrapper return checkParams @isadmin(userid="admin") def wrapperfun3(strname): def recoder(age): print("姓名:",strname,"年紀:",age) return recoder wrapperfun3=isadmin(userid="admin")(wrapperfun3) fun=wrapperfun3("Anana") fun(22)
通過裝飾器實現網站爬取中的重試功能
import requests
def retry(attempt): #定義裝飾器函式
def decorator(func):
def wrapper(*args,**kw):
att=0
while att<attempt: #按照計數器att的條件來執行迴圈語句
print(att)
try: #使用try except捕獲異常
return func(*args,**kw) #執行請求
except Exception as e:
att+=1 #調整計數器
return wrapper
return decorator
@retry(attempt=3)
def get_response(url):
r=requests.get(url)
return r
URL="http://www.baidu.com"
r=get_response(URL)
print(r)
if (r!=None):
print(r.content.decode("utf-8"))