day4-装饰器

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


原则:
1.不能修改被装饰的函数的源代码
2.不能修改被装饰的函数的调用方法
 
实现装饰器知识储备


1.函数即变量


2.高阶函数


a.把一个函数名当做实参传给另一个函数(在不修改被装饰函数源代码的情况下为其添加功能)
b.返回值中包含函数名(不修改函数的调用方式)

 

 1 import time
 2 
 3 # 定义一个bar函数
 4 def bar():
 5  time.sleep(3)
 6  print('in the bar')
 7 
 8 # 参数为函数名,返回值包含函数名
 9 def test2(func):
10  print(func)
11  return func
12  
13 # 把bar函数名当参数传给test2, 此时返回的是bar函数的地址
14 bar = test2(bar)
15 # 调用bar函数
16 bar()

 


3.嵌套函数

一个函数的函数体内,用def 去声明一个函数,而不是去调用其他函数,称为嵌套函数。

1 def timmer(func):
2  def wrapper(*args,**kwargs):
3   start_time = time.time
4   func(*args,**kwargs)
5   stop_time = time.time()
6   print('the func run time is %s' % (stop_time-start_time))
7  return warpper

 

 

高阶函数+嵌套函数 =》 装饰器

我们把上面的组合下:

 1 @timer =>(等于) test1=timer(test1)
 2 def test1():
 3  time.sleep(3)
 4  print('in the test1')
 5  
 6 def test2(name):
 7  print name
 8  
 9 test1()
10 test2()

 

 

复杂用法:装饰器带参数

 1 import time
 2 user,passwd = 'alex','abc123'
 3 def auth(auth_type):
 4     print("auth func:",auth_type)
 5     def outer_wrapper(func):
 6         def wrapper(*args, **kwargs):
 7             print("wrapper func args:", *args, **kwargs)
 8             if auth_type == "local":
 9                 username = input("Username:").strip()
10                 password = input("Password:").strip()
11                 if user == username and passwd == password:
12                     print("\033[32;1mUser has passed authentication\033[0m")
13                     res = func(*args, **kwargs)  # from home
14                     print("---after authenticaion ")
15                     return res
16                 else:
17                     exit("\033[31;1mInvalid username or password\033[0m")
18             elif auth_type == "ldap":
19                 print("搞毛线ldap,不会。。。。")
20         return wrapper
21     return outer_wrapper
22 def index():
23     print("welcome to index page")
24 
25 @auth(auth_type="local") # home = wrapper()
26 def home():
27     print("welcome to home  page")
28     return "from home"
29 @auth(auth_type="ldap")
30 def bbs():
31     print("welcome to bbs  page")
32 index()
33 print(home()) #wrapper()
34 bbs()

 

 

补充知识点(函数即变量、回收机制):

Python内存机制 : 比如赋值x=1,python会在内存中画个小房子,然后把1存进去,门牌号挂为x; 如果是函数,则把函数体存到内存里,以函数名为门牌号

Python回收机制:没有门牌号=》没有引用的时候

匿名函数: 没有门牌号,立马被回收
calc = lambda x: x*3
print(calc(3))

如果没有使用del方法删除,则一直被占用,直到程序结束,del方法删除的事门牌号,Python定期检查,若没有发现门牌号,则回收

 

posted @ 2017-06-12 22:49  不知所以  阅读(95)  评论(0)    收藏  举报