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
