python学习-day6-装饰器

一、装饰器的基本介绍

定义:装饰器本质是函数,(装饰其它函数)就是为其它函数添加附加功能

原则:

  • a,不能修改被装饰的函数的源代码
  • b,不能修改被装饰的函数的调用方式

实现:

  • 函数即“变量”,(函数可以像变量一样用来赋值,如func1 = func2)
  • 高阶函数:1,把一个函数名当作实参传给另一个函数;2,返回值中包含函数名
  • 嵌套函数:def func1():def func2():pass

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

知识点:

作用域的取值是从内到外一层层的找

函数的调用,内存,返回值及赋值

 1 def home_page():
 2     print(("home page").title().center(30,'@'))
 3     return 'from home'
 4 print(home_page())      #函数名加括号,表示执行函数,这里表示先调用函数,再打印函数的返回值
 5 print('第一个')
 6 print(home_page)        #函数名指向的是一个内存地址,存的内容就是函数的内容,但是没有调用,打印的是它的内存地址
 7 print('第二个')
 8 a = home_page()         #函数先调用,然后将返回值赋给a,a = 'from home',但是不打印a的值。如果函数没有return,那么a = None
 9 print('第三个')
10 print(a)                #打印a,a = 'from home'
11 print('第四个')
12 a = home_page              #将函数home_page当作一个变量赋给a,那么a就是一个函数,和home_page一样(没有输出)
13 print('第五个')
14 a()                       #执行函数a,返回值不打印,和home_page()一样
15 print('第六个')
16 print(a())                #相当于print(home_page()) ,先调用,再打印返回值
17 print('第七个')

输出为:

 1 @@@@@@@@@@Home Page@@@@@@@@@@@
 2 from home
 3 第一个
 4 <function home_page at 0x000000000081E1E0>
 5 第二个
 6 @@@@@@@@@@Home Page@@@@@@@@@@@
 7 第三个
 8 from home
 9 第四个
10 第五个
11 @@@@@@@@@@Home Page@@@@@@@@@@@
12 第六个
13 @@@@@@@@@@Home Page@@@@@@@@@@@
14 from home
15 第七个

装饰器最少两层:满足嵌套函数的要求。

最里面一层就是要装饰的函数实现的功能(调用最里层函数就相当于调用要装饰的函数)

外一层就是以要装饰的函数为参数,并返回最里面一层的函数

如果装饰器也需要加参数的话,那么外面再加一层函数,参数就是装饰器的参数,返回里面一层的函数名

实例:

1,被装饰的函数没有参数

 1 def login(func):        #func代表要装饰的函数名称
 2     def inner():    #为vip_page和home_page连个函数添加验证登录的功能
 3         user,password = 'cq','123'
 4         while True:
 5             user_name = input('>>>')
 6             pass_word = input('>>>')
 7             if user_name == user and pass_word == password:
 8                 func()         #这里的func()相当于vip_page()。。
 9                 break
10     return inner            #最外层函数返回里面一层的函数名称,不能加(),否则返回的是调用结果
11 
12 def index_page():
13     print("head page".title().center(30,'*'))
14 @login      #vip_page = inner(vip_page)
15 def vip_page():
16     print("vip page".title().center(30,'-'))
17 @login
18 def home_page():
19     print(("home page").title().center(30,'@'))
20     return 'from home'
21 def nomal_page():
22     print("nomal page".title())
23 
24 index_page()
25 vip_page()    #并没有改变原来的调用方式,就增加了验证登录的功能
26 home_page() 
27 nomal_page()

输出:

**********Head Page***********
>>>cq
>>>123
-----------Vip Page-----------
>>>cq
>>>123
@@@@@@@@@@Home Page@@@@@@@@@@@
Nomal Page

2,被装饰的函数有参数

如果函数home_page有个参数,home_page(name)怎么办,另外如果函数vip_page有个返回值怎么办

 1 def login(func):
 2     def inner(*args,**kwargs):      ##增加两个非固定参数,相当于inner(*args,**kwargs) = home_page(*args,**kwargs)
 3         user,password = 'cq','123'
 4         while True:
 5             user_name = input('>>>')
 6             pass_word = input('>>>')
 7             if user_name == user and pass_word == password:
 8                 res = func(*args,**kwargs)      #调用兵执行func,将返回值赋给res
 9                 return  res     #返回res,相当于返回vip_page()执行后的值
10                 break
11     return inner
12 
13 def index_page():
14     print("head page".title().center(30,'*'))
15 @login
16 def vip_page():
17     print("vip page".title().center(30,'-'))
18     return 'from home'
19 @login
20 def home_page(user):
21     print(("home page %s"%user).title().center(30,'@'))
22 def nomal_page():
23     print("nomal page".title())
24 
25 index_page()
26 print(vip_page())  ##调用并打印vip_page的返回值
27 home_page('laocui')
28 nomal_page()

输出:


**********Head Page***********
>>>cq
>>>123
-----------Vip Page-----------
from home
>>>cq
>>>123
@@@@@@@Home Page Laocui@@@@@@@    #参数打印了出来
Nomal Page

3,装饰器有参数

再增加一个功能,如果登录类型是local,那么还是按照上面判断用户名那样执行,如果,登录类型是ldap,那么直接退出

 1 def login(log_type):            #此参数代表装饰器的参数
 2     def outer(func):            #参数是要装饰的函数
 3         def inner(*args,**kwargs):
 4             user,password = 'cq','123'
 5             if log_type == 'local':
 6                 while True:
 7                     user_name = input('>>>')
 8                     pass_word = input('>>>')
 9                     if user_name == user and pass_word == password:
10                         res = func(*args,**kwargs)
11                         return res
12                         break
13             elif log_type == 'ldap':        #如果登录类型是ladap,那么不要登录
14                 print('暂时不会ldap。。。。')
15         return inner            #每个都要返回里面一层的函数名称
16     return outer        #每个都要返回里面一层的函数名称
17 
18 def index_page():
19     print("head page".title().center(30,'*'))
20 @login('ldap')
21 def vip_page():
22     print("vip page".title().center(30,'-'))
23 @login('local')
24 def home_page(user):
25     print(("home page %s"%user).title().center(30,'@'))
26     return 'from home'
27 def nomal_page():
28     print("nomal page".title())

输出:

**********Head Page***********
暂时不会ldap。。。。
>>>cq
>>>123
@@@@@@@@@Home Page Cq@@@@@@@@@
from home
Nomal Page
原文地址:https://www.cnblogs.com/cq90/p/6843417.html