装饰器

(1)介绍

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

原则:(1)不修改被装饰函数的源代码(开放封闭原则)

         (2)为被装饰函数添加新功能后,不修改被修饰函数的调用方式

组成:高阶函数、嵌套函数、闭包

(2)组成分析

高阶函数定义:

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

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

3.满足上述条件任意一个,都可称之为高阶函数

 1 #仅仅使用高阶函数实现函数增加功能
 2 import time#导入时间模块
 3 def use_1():#原函数
 4     time.sleep(3)
 5     print("hello")
 6 def fo(func):#高阶函数
 7     start_time = time.time()
 8     func()#当传入的参数为函数名时,此时便会执行该函数
 9     end_time = time.time()
10     print("函数运行的时间是%s"%(end_time-start_time))#添加时间计算功能
11     return func
12 use_1 = fo(use_1)#函数的返回值是一个函数名,可以用原变量接受
13 use_1()#在此基础上,可以以原来调用方式调用该函数
14 #打印结果
15 #hello
16 #函数运行的时间是3.000171661376953
17 #hello

由上面函数可知,当只使用高阶函数来为目标函数增加功能时,虽然没有改变原函数的源代码跟执行方式,但不可避免的是函数会执行第二次

嵌套函数:在函数内定义新函数,函数内变量查找遵循L(local)、E(enclosed)、G(global)、B(built)

1 # def qt(func):#
2 #     def inner():
3 #         def oc():
4 #             print(func)#变量查找遵循LEGB原则
5 #         oc()
6 #     inner()
7 # qt("hello")#将hello赋值给参数func

闭包:

如果在一个内部函数里:us(y)就是这个内部函数,
对在外部作用域(但不是在全局作用域)的变量进行引用:x就是被引用的变量,x在外部作用域occ里面,但不在全局作用域里,
则这个内部函数us就是一个闭包。
1 def occ(x):
2     def us(y):#us是闭包
3         print( x + y )#对外部作用域变量x进行引用
4     return us
5 aa = occ(6)
6 aa(4)#

(3)装饰器

注意:@为python内置方法,等价于目标函数名=装饰器函数名(目标函数名),装饰器函数写好,哪个函数要调用直接在其上部写@装饰器名字即可

 1 import time
 2 def abc(func):
 3     def ooo(*args,**kwargs):
 4         start_time = time.time()
 5         res = func(*args,**kwargs)
 6         end_time = time.time()
 7         print("函数运行时间为%s"%(end_time-start_time))
 8         return res
 9     return ooo
10 @abc#@为python内置方法,等价于aaa=abc(aaa),装饰器函数写好,哪个函数要调用直接在其上部写@装饰器名字即可
11 def aaa(*args,**kwargs):
12     time.sleep(2)
13     print("运行函数了!")
14     print("函数运行结束了!")
15     return "这是aaa的返回值"
16 ccc = aaa()#注意,此时的ccc接受到的是ooo()函数的返回值,并非aaa()的返回值
17 print(ccc)

例子:

不含参数的装饰器

 1 use_list = [{"name":"tom","passwd":“123”},
 2             {"name":"eric","passwd":“123”}]
 3 use_time = {"name":None,"log":False}
 4 
 5 def ente(func):
 6     # use_name = input("请输入用户名:").strip()
 7     # use_passwd = input("请输入密码:").strip()
 8     def en(*args,**kwargs):
 9         if use_time["name"] and use_time["log"]:
10             res = func(*args,**kwargs)
11             return res
12         use_name = input("请输入用户名:").strip()
13         use_passwd = input("请输入密码:").strip()
14         for i in use_list:
15             if use_name == i["name"] and use_passwd == i["passwd"]:
16                 use_time["name"] = use_name
17                 use_time["passwd"] = use_passwd
18                 res = func(*args,**kwargs)
19                 return res
20         else:
21             print("用户名或密码错误!")
22     return en
23 @ente
24 def home():
25     print("欢迎来到京东主页!")
26 @ente
27 def shopping_list():
28     print("欢迎来到shoping_list!")
29 @ente
30 def shoping_car():
31     print("欢迎来到shoping_car!")
32 home()
33 shopping_list()

 含参数的装饰器

 1 use_list = [{"name":"tom","passwd":"123"},
 2             {"name":"eric","passwd":"123"}]
 3 use_time = {"name":None,"log":False}
 4 def firt(ente_1 = "test")
 5     def ente(func):
 6         # use_name = input("请输入用户名:").strip()
 7         # use_passwd = input("请输入密码:").strip()
 8         def en(*args,**kwargs):
 9             if use_time["name"] and use_time["log"]:
10                 res = func(*args,**kwargs)
11                 return res
12             use_name = input("请输入用户名:").strip()
13             use_passwd = input("请输入密码:").strip()
14             for i in use_list:
15                 print(i["name"],i["passwd"])
16                 if use_name == i["name"] and use_passwd == i["passwd"]:
17                     use_time["name"] = use_name
18                     use_time["log"] = True
19                     res = func(*args,**kwargs)
20                     return res
21             else:
22                 print("用户名或密码错误!")
23         return en
24     return ente
25 @firt(ente_1 = "test")#相当于运行firt函数,返回entc函数名,结果等价于@ente,好处是最外层传入了一个参数,内层的闭包函数可以直接引用
26 def home():
27     print("欢迎来到京东主页!")
28 @firt(ente_1 = "test")
29 def shopping_list():
30     print("欢迎来到shoping_list!")
31 @firt(ente_1 = "test")
32 def shoping_car():
33     print("欢迎来到shoping_car!")
34 home()
35 shopping_list()

 

posted @ 2016-12-07 21:15  amchen  阅读(220)  评论(0编辑  收藏  举报