Python学习(十)—— 装饰器和函数闭包

装饰器

装饰器:本质就是函数,功能是为其他函数添加附加功能

原则:

1、不修改被修饰函数的源代码

2、不修改被修饰函数的调用方式

统计程序运行的时间(不使用装饰器):

  这种方法修改了源代码,不能用于已经上线的程序

 1 import time
 2 def calc(l):
 3     res = 0
 4     start_time = time.time()
 5     for i in l:
 6         res += i
 7         time.sleep(0.01)
 8     stop_time = time.time()
 9     print(stop_time - start_time)
10     return res
11 
12 y = calc([1,2,3,4,5,6,7,8,9,10])
13 print(y)
14 # 0.1087961196899414
15 # 55

  这种方法修改了调用方式

 1 import time
 2 def timmer(func):
 3     start_time = time.time()
 4     y = func()
 5     stop_time = time.time()
 6     print(stop_time - start_time,"\n",y)
 7     return timmer
 8 
 9 def calc():
10     res = 0
11     for i in range(1,11):
12         res += i
13         time.sleep(0.01)
14     return res
15 
16 timmer(calc)
17 
18 # 0.10875916481018066 
19 #  55

统计程序运行的时间(使用装饰器):

 1 import time
 2 def timmer(func):
 3     def wrapper(*args,**kwargs):
 4         start_time = time.time()
 5         res = func(*args,**kwargs)
 6         stop_time = time.time()
 7         print(stop_time - start_time)
 8         return res
 9     return wrapper
10 @timmer
11 def calc(l):
12     res = 0
13     for i in l:
14         res += i
15         time.sleep(0.01)
16     return res
17 
18 y = calc([1,2,3,4,5,6,7,8,9,10])
19 print(y)
20 # 0.10654282569885254
21 # 55

装饰器 = 高阶函数 + 函数嵌套 + 闭包

高阶函数 

高阶函数的定义:满足下列任一条即可

1、函数接收的参数是一个函数名

2、函数的返回值是一个函数名

函数嵌套 

在函数内部嵌套另一个函数

闭包

装饰器的框架

 1 import time
 2 def timmer(func): #参数是函数
 3     def wrapper(): #函数的嵌套
 4         start_time= time.time()
 5         # print(func)
 6         func() #函数闭包所以可以调用func
 7         end_time = time.time()
 8         print("running time is %s"%( end_time-start_time))
 9     return wrapper #返回是函数
10 @timmer  #装饰器名,相当于test = timmer(test),置于被修饰函数之前
11 def test():
12     time.sleep(3)
13 
14 test()
15 # running time is 3.000131368637085

有参数的情况下框架:

 1 import time
 2 def timmer(func): #参数是函数
 3     def wrapper(*args,**kwargs): #函数的嵌套
 4         s_time = time.time()
 5         func(*args,**kwargs) #函数闭包所以可以调用func
 6         e_time = time.time()
 7         print("running time :" ,e_time-s_time)
 8     return wrapper #返回是函数
 9 @timmer
10 def test(name,gender,age):
11     time.sleep(3)
12     print(name)
13     print(gender)
14     print(age)
15 
16 test("ally","female",20)
17 # ally
18 # female
19 # 20
20 # running time : 3.000988245010376

例子

  给主页加登录装饰器(出现重复登录情况)

 1 #!/usr/bin/env python 
 2 # -*- coding:utf-8 -*-
 3 def login(func):
 4     def wragger(*args, **kwargs):
 5         x = input("请输入用户名:")
 6         y = int(input("请输入密码:"))
 7         if x == "admin" and y == 123456:
 8             print("登录成功")
 9             res = func(*args, **kwargs)
10             return res
11         else:
12             pass
13 
14     return wragger
15 
16 
17 @login
18 def index():
19     print("欢迎来到京东")
20 
21 
22 @login
23 def home():
24     print("欢迎回家")
25 
26 
27 @login
28 def shopping_car():
29     print("我的购物车")
30 
31 
32 @login
33 def order():
34     print("我的订单")
35 
36 
37 index()
38 # 请输入用户名:admin
39 # 请输入密码:123456
40 # 登录成功
41 # 欢迎来到京东
View Code

  给主页加登录装饰器的例子(不需重复登录)

 1 user_dic ={"user_name":None,"login":False}
 2 def auth_login(func):
 3     def wragger(*args, **kwargs):
 4         if user_dic["user_name"] and user_dic["login"]:
 5             res = func(*args, **kwargs)
 6             return res
 7         else:
 8             user_name = input("请输入用户名:")
 9             password = int(input("请输入密码:"))
10             if user_name == "admin" and password == 123456:
11                 user_dic["user_name"] = user_name
12                 user_dic["login"] = True
13                 print("登录成功")
14                 res = func(*args, **kwargs)
15                 return res
16     return wragger
17 
18 
19 @auth_login
20 def index():
21     print("欢迎来到京东")
22 
23 
24 @auth_login
25 def home():
26     print("欢迎回家")
27 
28 
29 @auth_login
30 def shopping_car():
31     print("我的购物车")
32 
33 
34 @auth_login
35 def order():
36     print("我的订单")
37 
38 index()
39 shopping_car()
40 order()
41 
42 # 请输入用户名:admin
43 # 请输入密码:123456
44 # 登录成功
45 # 欢迎来到京东
46 # 我的购物车
47 # 我的订单
View Code

  公司有多个用户

 1 #!/usr/bin/env python 
 2 # -*- coding:utf-8 -*-
 3 user_list = [
 4     {"user_name": "alex", "password": "123"},
 5     {"user_name": "admin", "password": "123456"},
 6 ]
 7 user_login = {"user_name": None, "login": False}
 8 
 9 def auth_login(func):
10     def wragger(*args, **kwargs):
11         if user_login["user_name"] and user_login["login"]:
12             res = func(*args, **kwargs)
13             return res
14         else:
15             user_name = input("请输入用户名:").strip()
16             password = input("请输入密码:").strip()
17             for user_dic in user_list:
18                 if user_name == user_dic["user_name"] and password == user_dic["password"]:
19                     user_login["user_name"] = user_name
20                     user_login["login"] = True
21                     print("登录成功")
22                     res = func(*args, **kwargs)
23                     return res
24             else:
25                 print("用户或密码错误")
26     return wragger
27 
28 @auth_login
29 def index():
30     print("欢迎来到京东")
31 
32 @auth_login
33 def home():
34     print("欢迎回家")
35 
36 @auth_login
37 def shopping_car():
38     print("我的购物车")
39 
40 @auth_login
41 def order():
42     print("我的订单")
43 
44 index()
45 shopping_car()
46 order()
47 
48 # 请输入用户名:admin
49 # 请输入密码:123456
50 # 登录成功
51 # 欢迎来到京东
52 # 我的购物车
53 # 我的订单

函数闭包带参数装饰器

解压序列 

交换值

1 f1 = 1
2 f2 = 2
3 f1,f2 = f2,f1
4 print(f1,f2)
5 # 2 1

一条语句多变量赋值,必须一一对应

 1 a,b,c = "hel"
 2 print("a:",a,"\nb:",b,"\nc:",c)
 3 # a: h
 4 # b: e
 5 # c: l
 6 x,y,z = 1,3,5
 7 print("x:",x,"\ny:",y,"\nz:",z)
 8 # x: 1
 9 # y: 3
10 # z: 5
11 u,v = [1,2],[4,5]
12 print(u,v)
13 # [1, 2] [4, 5]

如果只想取出特定值,可以不用索引

1 l = [0,1,2,3,4,5,6,7,8,9]
2 a,*_,b = l #实际上,可以使用*+任何字母或符号
3 print(a)
4 print(b)
5 # 0
6 # 9

猜你喜欢

转载自www.cnblogs.com/jennifer224/p/12399008.html