Python 3 学习笔记(六)----装饰器

一、定义

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

二、装饰器原则

1.不能修改被装饰的函数的源代码

2.不能修改被装饰的函数的调用方式

三、实现装饰器的必要知识

1.函数即是变量

 1 # def foo():
 2 #     print("in the foo")
 3 #     bar()    #bar未定义
 4 # foo()
 5 
 6 
 7 # def bar():
 8 #     print("int the bar")
 9 # def foo():
10 #     print("in the foo")
11 #     bar()
12 # foo()
13 
14 
15 # def foo():
16 #     print("in the foo")
17 #     bar()
18 # def bar():
19 #     print("int the bar")
20 # foo()
1 def foo():
2     print("in the foo")
3     bar()
4 foo()
5 def bar():  #在调用后定义不会执行
6     print("int the bar")

2.高阶函数(高阶函数的两种表达方式)

2.1把一个函数名当作实参传给另外一个函数(在不修改被装饰函数源代码的情况下为其添加功能)

 1 import time
 2 
 3  def bar():
 4      time.sleep(3)
 5      print("in the bar")
 6 
 7  def test1(func):
 8      start_time = time.time()
 9      func()
10      stop_time = time.time()
11      print("the func run time is %s" %(stop_time-start_time))
12  test1(bar)

2.2返回值中包含函数名

 1 import time
 2 def bar():
 3     time.sleep(3)
 4     print("in the bar")
 5 def test2(func):
 6     print(func)
 7     return func#返回为内存地址
 8 
 9 #print(test2(bar))
10 # t=test2(bar)
11 # t() #run bar
12 bar=test2(bar)
13 bar() #返回的内存地址加上()就可以执行

3.嵌套函数

 1 x=0
 2 def a():
 3     x=1
 4     def b():
 5         x=2
 6         def c():
 7             x=3
 8             print(x)
 9         c()
10     b() #此处如果不执行b(),那么函数相当于什么都没干,因为没有print
11 a()

四、装饰器=高阶函数+嵌套函数

 1 import time
 2 
 3 def timer(func):  #timer(test)  func=test
 4     def deco():
 5         start_time = time.time()
 6         func()   #此处运行被装饰函数test
 7         stop_time = time.time()
 8         print("func run time is %s" %(stop_time-start_time))
 9     return deco  #返回deco的内存地址
10 
11 
12 @timer   #相当于timer=timer(test),装饰器永远放在被装饰的函数前
13 def test():
14     time.sleep(3)
15     print("this is test")
16 
17 test()

五、如果装饰器的函数中包含参数

 1 import time
 2 
 3 def timer(func):
 4     def deco(*args,**kwargs):  #*args,**kwargs代表参数不确定的意思
 5         start_time=time.time()
 6         func(*args,**kwargs)
 7         stop_time=time.time()
 8         print("in the run time is %s" %(stop_time-start_time))
 9     return deco
10 
11 @timer   # test2 = timer(test2) = deco    test2(name) = deco(name)
12 def test2(age,name,job):
13     time.sleep(1)
14     print("test2:",age,name,job)
15 
16 test2(23,"Irlo","seller")

六、装饰器的使用实例

假设为网页添加登陆验证

 1 user,pasd = "Irlo","12345"
 2 def auth(auth_type):
 3     print("auth func is",auth_type)
 4     def type(func):
 5         def wrapper():
 6             if auth_type == "local":
 7                 username = input("username:").strip()  #strip移除字符串首尾指定的字符(默认为空格)
 8                 password = input("password:").strip()
 9                 if user==username and pasd==password:
10                     print("33[1;32;1mauthority of account33[0m") #高亮显示的格式(33[显示方式;前景色;背景色m)
11                     res=func()  #将结果赋值给一个变量才能在之后调用home有结果
12                     print("after authentication")
13                     return res  #如果不返回,相当于执行完就结束了,没有返回值是一个空值
14                 else:
15                     print(" invalid username or password ")
16             elif auth_type == "ldap":
17                 print("I just know local,fuck off")
18         return wrapper
19     return type
20 
21 def index():
22     print("welcome to index page")
23 
24 @auth(auth_type = "local")
25 def home():
26     print("welcome to home page")
27     return "from home"
28 
29 @auth(auth_type = "ldap")
30 def bbs():
31     print("welcome to bbs page")
32 
33 index()
34 print(home()) #调用home的时候相当于是调用wrapper
35 home()
36 bbs()
原文地址:https://www.cnblogs.com/consort/p/7492507.html