在Python中的无参装饰器和有参装饰器
生活随笔
收集整理的這篇文章主要介紹了
在Python中的无参装饰器和有参装饰器
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
裝飾器特點:
1.開放封閉原則,即對擴展是開放的,對修改時封閉的;
2.裝飾器本質(zhì)可以是任意可調(diào)用的對象,被裝飾的對象也可以是任意可調(diào)用對象;
3.裝飾器的功能是在不修改被裝飾器對象源代碼以及被裝飾器對象的調(diào)用方式的前提下為其擴展新功能;
4.裝飾器本質(zhì)是函數(shù),(即裝飾其他函數(shù))就是為其他函數(shù)添加附加功能。
裝飾器其實就是對函數(shù)的理解與運用(函數(shù)對象與閉包函數(shù))
一 ,典型的案例:
#裝飾器的語法:在被裝飾對象的正上方的單獨一行,@裝飾器名字 import time import randomdef RunTime(TheCaller): #定義裝飾器def MyCaller():start_time = time.time()TheCaller()stop_time=time.time()print('run time is %s' %(stop_time-start_time))return MyCaller#被裝飾函數(shù) @RunTime #等效于index=RunTime(index) def index():time.sleep(random.randrange(2,4)) #可以在1-3秒鐘(不包括4秒喲)隨機睡眠指定范圍的時長。print('welecome to INDEX page')@RunTime #home=RunTime(home) def home():time.sleep(random.randrange(1,2))print('welecome to HOME page')index() #MyCaller() home() #以上代碼執(zhí)行結(jié)果如下: welecome to INDEX page run time is 2.0000088214874268 welecome to HOME page run time is 1.0006351470947266二,多個裝飾器的案例
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' #!/usr/bin/env python #裝飾器的語法:在被裝飾對象的正上方的單獨一行,@裝飾器名字 import time import random from functools import wrapsdef RunTime(TheCaller): #定義裝飾器+@wraps(TheCaller) #可以讓用戶查看幫助信息的時候查看其自己的源代碼定義的幫助信息。def MyCaller(*args,**kwargs):'''Runtime's help information'''start_time = time.time()res = TheCaller(*args,**kwargs)stop_time=time.time()print('run time is %s' %(stop_time-start_time))return resreturn MyCallerdef NewAddAuth(TheCaller):def Auth(*args,**kwargs):name=input('username: ')password=input('password: ')if name == 'rianley' and password == '123':print('login successful')res = TheCaller(*args,**kwargs)return reselse:print('login error')return Auth#被裝飾函數(shù) # @NewAddAuth @RunTime #等效于index=RunTime(index),裝飾器的執(zhí)行順序是自下而上。 def Index():'''Index's help information'''time.sleep(random.randrange(2,4)) #可以在1-3秒鐘(不包括4秒喲)隨機睡眠指定范圍的時長。print('welecome to INDEX page')return "rianleycheng"@RunTime #home=RunTime(home) def Home(name):'''Home's help information'''time.sleep(random.randrange(1,2))print('welecome to %s HOME page'%(name))return 666res1 = Index() #MyCaller() res2 = Home("程小航") print("Index return :%s"%(res1)) print("Home return :%s"%(res2)) # print(help(Index)) # print(Index().__doc__) #以上代碼執(zhí)行結(jié)果如下: welecome to INDEX page run time is 3.000018835067749 welecome to 程小航 HOME page run time is 1.0001890659332275 Index return :rianleycheng Home return :666三,有參裝飾器
''' 編寫裝飾器,為多個函數(shù)加上認(rèn)證的功能(用戶的賬號密碼來源于文件),要求登陸成功一次,后續(xù)的函數(shù)都無需再驗證。 ''' # user_dic = { # 'rianley':'123', # 'Golang':"666", # 'Python':"888", # } # # with open("user.db","w",encoding="utf-8")as f: # f.write(str(user_dic)) db_path = "user.db"login_dic ={'user':None,"status":False, }def Decorator(AuthType="file"):def auth(func):def wrapper(*args, **kwargs):if AuthType == "file":if login_dic['user'] and login_dic['status']:res = func(*args, **kwargs)return resusername = input("username:")password = input("password:")with open(db_path, "r", encoding="utf-8")as f:user_dic = eval(f.read())if username in user_dic and password == user_dic[username]:print('login successful')login_dic['user'] = usernamelogin_dic['status'] = Trueres = func(*args, **kwargs)return reselse:print('login error')elif AuthType == "ldap":print("LDAP認(rèn)證方式")elif AuthType == "MySQL":print("MySQL認(rèn)證方式")else:print("其他認(rèn)證方式")return wrapperreturn auth@Decorator() def Index():print("Welcome to Index!")@Decorator(AuthType="MySQL") def home(name):print("Welecome %s to home page!"%name)Index() home("程小航") #以上代碼執(zhí)行結(jié)果如下: username:rianley password:123 login successful Welcome to Index! MySQL認(rèn)證方式四.小試牛刀
1.編寫裝飾器,為多個函數(shù)加上認(rèn)證的功能(用戶的賬號密碼來源于文件),要求登陸成功一次,后續(xù)的函數(shù)都無需再驗證。
# user_dic = { # 'rianley':'123', # 'Golang':"666", # 'Python':"888", # } # # with open("user.db","w",encoding="utf-8")as f: # f.write(str(user_dic))db_path = "user.db"login_dic ={'user':None,"status":False, }def auth(func):def wrapper(*args,**kwargs):if login_dic['user'] and login_dic['status']:res = func(*args, **kwargs)return resusername = input("username:")password = input("password:")with open(db_path, "r", encoding="utf-8")as f:user_dic = eval(f.read())if username in user_dic and password == user_dic[username]:print('login successful')login_dic['user'] = usernamelogin_dic['status'] = Trueres = func(*args,**kwargs)return reselse:print('login error')return wrapper@auth def Index():print("Welcome to Index!")@auth def home(name):print("Welecome %s to home page!"%name)Index() home("程小航")以上代碼執(zhí)行結(jié)果如下: username:rianley password:123 login successful Welcome to Index! Welecome 程小航 to home page!2.編寫下載網(wǎng)頁內(nèi)容的函數(shù),要求功能是:用戶傳入一個URL,函數(shù)返回下載頁面的內(nèi)容。
''' 遇到問題沒人解答?小編創(chuàng)建了一個Python學(xué)習(xí)交流QQ群:579817333 尋找有志同道合的小伙伴,互幫互助,群里還有不錯的視頻學(xué)習(xí)教程和PDF電子書! ''' from urllib.request import urlopen import oscache_path=r'cache.txt' def make_cache(func):def wrapper(*args,**kwargs):if os.path.getsize(cache_path):#說明有緩存print('\033[45m=========有緩存=========\033[0m')with open(cache_path,'rb') as f:res=f.read()else:res=func(*args,**kwargs) #下載with open(cache_path,'wb') as f: #制作緩存f.write(res)return resreturn wrapper@make_cache def get(url):return urlopen(url).read()print('============first============') print(get('http://www.cnblogs.com/rianley')) print('============second===========') print(get('http://www.cnblogs.com/rianley')) print('============third============') print(get('http://www.cnblogs.com/rianley'))3.裝飾器包裝原函數(shù)案例
FuncDict={}def MakeDict(key):def deco(func):FuncDict[key]=func# def wrapper(*args,**kwargs): #此行及以下3行可以不寫,這樣就可以達(dá)到隱藏你原來函數(shù)的名字。# res = func(*args,**kwargs)# return res# return wrapperreturn deco @MakeDict("one") def First():print("From Shell")@MakeDict("two") def Second():print("From Second")@MakeDict("three") def Third():print("From Third")print(FuncDict)while True:cmd = input(">>>:").strip()if cmd in FuncDict:FuncDict[cmd]() #以上代碼執(zhí)行結(jié)果如下: {'one': <function First at 0x027E38E8>, 'two': <function Second at 0x027E3810>, 'three': <function Third at 0x027E38A0>} >>>:three From Third >>>:one From Shell >>>:two From Second >>>: >>>: >>>:總結(jié)
以上是生活随笔為你收集整理的在Python中的无参装饰器和有参装饰器的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: PHP 与Python 读取大文件的区别
- 下一篇: Python中数据的保存和读取