Python小程序练习二之装饰器小例子
装饰器:
装饰器实际上就是为了给某程序增添功能,但该程序已经上线或已经被使用,那么就不能大批量的修改源代码,这样是不科学的也是不现实的,因为就产生了装饰器,使得其满足:
1、不能修改被装饰的函数的源代码
2、不能修改被装饰的函数的调用方式
那么根据需求,同时满足了这两点原则,这才是我们的目的。
装饰器的原则组成:
< 函数+实参高阶函数+返回值高阶函数+嵌套函数+语法糖 = 装饰器 >
错误例子:
1、1Decorators.py
1 # The author is tou 2 # Version:Python 3.6.5 3 import time 4 5 def timer(func): 6 start_time = time.time() 7 func() 8 stop_time = time.time() 9 print("The func run time is :",(stop_time-start_time)) 10 11 @timer 12 def test1(): 13 time.sleep(1) #停1秒打印 14 print("This is test1") 15 @timer 16 def test2(): 17 time.sleep(1) #停1秒打印 18 print("This is test2") 19 #test1() 20 #test2()
你会发现当不调用test1()和test2()时,程序正常运行,调用test1()和test2()时便会出现TypeError: 'NoneType' object is not callable(对象不可调用)的错误,该程序只用了函数+实参高阶函数,并没有用到返回值高阶函数和嵌套函数。
正确例子
2、2Decorators.py
1 # The author is tou 2 # Version:Python 3.6.5 3 import time 4 5 def timer(func): 6 def dooc(): 7 start_time = time.time() 8 func() 9 stop_time = time.time() 10 print("The func run time is :",(stop_time-start_time)) 11 return dooc 12 13 #@timer 14 def test1(): 15 time.sleep(1) #停1秒打印 16 print("This is test1") 17 test1 = timer(test1) 18 @timer 19 def test2(): 20 time.sleep(1) #停1秒打印 21 print("This is test2") 22 test1() 23 test2()
装饰器在装饰时,需要在每个函数前面加上:@timer这是Python提供的一种语法糖
其实它和 test1 = timer(test1) 是等价的,只要在函数前加上这句,就可以实现装饰作用。test1()和test2()的运行效果是一样的
3、3Decorators.py
当调用函数需要传递参数时,timer函数就不能满足要求,可修改为一下形式。使其对传不传参数都可以使用装饰器。
1 # The author is tou 2 # Version:Python 3.6.5 3 import time 4 5 def timer(func): 6 def dooc(*args,**kwargs): 7 start_time = time.time() 8 func(*args,**kwargs) 9 stop_time = time.time() 10 print("The func run time is :", (stop_time - start_time)) 11 return dooc 12 13 @timer 14 def test1(): 15 time.sleep(1) # 停1秒打印 16 print("This is test1") 17 18 @timer 19 def test2(name): 20 time.sleep(1) # 停1秒打印 21 print("This is %s"%name) 22 23 test1() 24 test2("tou")
最后,通过一个需求来练习一下装饰器
现在有一个网站,首页不需要登陆,自己主页和BBS需要登陆,并且主页和BBS登陆方式不一样,主页采取local方式,BBS采用ldap方式。我们使用一个函数代表一个页面。
4、4Decorators.py
1 # The author is tou 2 # Version:Python 3.6.5 3 user_name,user_password = "tou","123456" 4 5 def request(request_type): 6 def type(func): 7 def dooc(*args,**kwargs): 8 if request_type == "local": 9 name = input("请输入您的用户名:").strip() 10 password = input("请输入您的密码:").strip() 11 if name == user_name and password == user_password: 12 print("\033[32;1m登陆成功!\033[0m") 13 res = func(*args,**kwargs) 14 return res 15 else: 16 exit("您输入的用户名或者密码错误!") 17 else: 18 print("\033[31;1m没有这种登陆方式\033[0m") 19 return dooc 20 return type 21 22 def index(): 23 print("欢迎进入首页") 24 @request(request_type = "local") 25 def home(): 26 print("欢迎进入您的主页") 27 return "来自home" 28 @request(request_type = "ldap") 29 def BBS(): 30 print("欢迎进入BBS主页") 31 32 index() 33 print(home()) 34 BBS()
来源:https://www.cnblogs.com/Henrytoutou/p/8811009.html