欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

装饰器

程序员文章站 2022-06-30 14:13:47
...

装饰器

1.装饰器

def w1(func):
	def inner():
		print("---正在验证权限---")
		func()
	return inner

@w1 #只要python解释器执行到这个代码那就回自动进行装饰,而不是等到调用的时候才装饰,就相当于 f1 = w1(f1) 
def f1():
	print("---f1---")

f1()

'''
输出结果:
---正在验证权限---
---f1---
'''

@w1就相当于 f1 = w1(f1) 执行这句话是 func 指向 f1 ,而return inner会直接使inner函数指向的地址直接返回给f1,此时的就指向闭包里面的inner函数,然后函数继续往下运行当运行到 f1() 时,就直接会运行 f1 指向的函数而此时 f1 指向的函数是inner所以就会首先打印 “—正在验证权限—” 继续往下运行会运行到 func() 时,此时func() 是指向原来的f1 函数的地址,所以就会打印原来f1 里面的那句话 “—1---”。这也就是为什么不会去调用f1函数时print("—正在验证权限—")也会被打印 的原因。
装饰器

调用的时候是从上往下调用,但是装饰的时候是从下往上装饰。

2.两个装饰器

 24	def Bold(func):
 25         print("正在装饰---1---")
 26         def inner():
 27                 print("---1---")
 28                 func()
 29         return inner
 30 
 31 def Italic(func):
 32         print("正在装饰---2---")
 33         def inner():
 34                 print("---2---")
 35                 func()
 36         return inner
 37 
 38 
 39 @Bold
 40 @Italic
 41 def f1():
 42         print("---结束---")
 43 f1()
 44'''
 45 输出结果:
 46 正在装饰---2---
 47 正在装饰---1---
 48 ---1---
 49 ---2---
 50 ---结束---
 51'''

装饰器
当两个装饰器一起对函数进行装饰时,是先从下面的装饰器开始装饰,因为装饰器遇到函数才会开始装饰,当程序运行到第一个装饰器时因为下面不是函数程序继续运行,到第二个装饰器时再往下运行就是函数所以就会进行装饰。

3.装饰器对有参数函数进行装饰

  1 def func(functionName):
  2         print("---func---1---")
  3         def func_in(a, b): #如果a,b没有定义,那么会导致第15行的调用失败
  4                 print("---func_in---1---")
  5                 functionName(a, b) #如果没有把 a,b当做实参进行传递,那么会导致调用12行的函数失败
  6                 print("---func_in---2---")
  7 
  8         print("---func---2---")
  9         return func_in
 10 
 11 @func
 12 def test(a, b):
 13         print("---a=%d,b=%d---"%(a, b))
 14 
 15 test(11,22)
 16 '''
 17 输出结果:
 18 ---func---1---
 19 ---func---2---
 20 ---func_in---1---
 21 ---a=11,b=22---
 22 ---func_in---2---
 23 '''

对不定长的参数进行装饰:

  1 def func(functionName):
  2         print("---func---1---")
  3         def func_in(*args, **kwargs):
  4                 print("---func_in---1---")
  5                 functionName(*args, **kwargs)
  6                 print("---func_in---2---")
  7 
  8         print("---func---2---")
  9         return func_in
 10 
 11 @func
 12 def test(a,b,c,d):
 13         print("---a=%d,b=%d,c=%d,d=%d---"%(a,b,c,d))
 14 
 15 test(11,22,33,44)
 16 
 17 '''
 18 输出结果:
 19 ---func---1---
 20 ---func---2---
 21 ---func_in---1---
 22 ---a=11,b=22,c=33,d=44---
 23 ---func_in---2---
 24 '''

4.对带有返回值的函数进行装饰

  1 def func(functionName):
  2         print("---1---")
  3         def func_in():
  4                 print("---func_---1---")
  5                 xxx = functionName() #xxx用来保存test函数返回来的haha
  6                 print("---func_in---2---")
  7                 return xxx #把haha返回到17行处的ret
  8 
  9         print("---func---2---")
 10         return func_in
 11 
 12 @func
 13 def test():
 14         print("---test---")
 15         return "haha"
 16 
 17 ret = test()
 18 print("test return value is %s"%ret)
 19 
 20 '''
 21 输出结果
 22 ---1---
 23 ---func---2---
 24 ---func_---1---
 25 ---test---
 26 ---func_in---2---
 27 test return value is frank
 28 '''
~              

装饰器
如果没有一个变量xxx去接收函数中return的值那么就无法完成装饰。

5.通用装饰器
在实际情况下我们不能去判断它有几个数,有没有返回值所以我们就要用一种通用的装饰器。

  1 def func(functionName):
  2         def func_in(*arg, **kwargs):
  3                 print("---记录日志---")
  4                 ret = functionName(*arg, **kwargs)
  5                 return ret
  6 
  7         return func_in
  8 
  9 @func
 10 def test():
 11         print("---test---")
 12         return "frank"
 13 
 14 @func
 15 def test2():
 16         print("---test2---")
 17 
 18 @func
 19 def test3(a):
 20         print("---test3--a=%d--"%a)
 21 
 22 ret = test()
 23 print("test return value is %s"%ret)
 24 
 25 a= test2()
 26 print("test2 return value is %s"%a)
 27 
 28 test3(11)
 29 
 30 '''
 31 输出结果:
 32 ---记录日志---
 33 ---test---
 34 test return value is frank
 35 ---记录日志---
 36 ---test2---
 37 test2 return value is None
 38 ---记录日志---
 39 ---test3--a=11--

6.带有参数的装饰器

  1 def func_arg(arg):
  2         def func(functionName):
  3                 def func_in():
  4                         print("---记录日志-arg=%s--"%arg)
  5                         if arg == "smile": #装饰器中不同的参数可以起到不同的功能
  6                                 functionName()
  7                                 functionName()
  8                         else:
  9                                 functionName()
 10                 return func_in
 11         return func
 12 
 13 
 14 #① 先执行func_arg("smile")函数,这个函数return的结果是func这个函数的引用
 15 #② 然后就相当于@func
 16 #③ 使用@func对test进行装饰
 17 @func_arg("smile")
 18 def test():
 19         print("---test---")
 20 
 21 
 22 @func_arg("haha")
 23 def test2():
 24         print("---test2---")
 25 
 26 test()
 27 test2()
 28 
 29 '''
 30 输出结果:
 31 ---记录日志-arg=smile--
 32 ---test--- 
 33 ---test---
 34 ---记录日志-arg=haha--
 35 ---test2---
 36 '''

带有参数的装饰器,能够起到在运行时有不同的功能。

相关标签: python

上一篇: DrawerLayout的使用

下一篇: 装饰器