Python小程序练习二之装饰器小例子

混江龙づ霸主 提交于 2019-11-28 04:35:49

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()
网站登录小练习
        在此,装饰器的小练习便结束了
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!