python 装饰器

时间:2019-08-28 15:28:54   收藏:0   阅读:78

一.装饰器概念与语法

python装饰器本质上就是一个嵌套函数,装饰器的返回值也是一个函数对象。简写:装饰器是以一个一函数为参数,返回值为函数的函数

语法:在需要装饰的类或者函数上面写@+函数名称。

二.装饰器的作用

 装饰器可以在不更改原功能代码情况下,可以扩展新的功能。

开放封闭原则:

1.以实现的功能,不要去修改其内部(被装饰的函数或类)代码(封闭原则)

2.对功能的扩展(装饰器的扩展)是开放的(开放原则)

三.装饰器的方法

1.函数(闭包函数)

1)函数内部嵌套函数

2)外层函数的返回值是内层函数的函数名

3)内层嵌套函数对外层有一个非全局变量的引用

2.类装饰器(__call__)

1)__call __()方法是将实例成为一个可调用对象(即callable对象),同时不影响实例的构造,但可以改变实例的内部值。

四.代码演示

1.闭包形式的装饰器

 1)闭包函数:符合上面三个条件

1 def func():
2     a=10
3     def func_01():
4         print(a)
5     return func_01()

2)装饰器:装饰函数

 1 def func(fu):  #外层函数的第一个参数类型为函数
 2     def func_02():
 3         print("新功能")
 4         fu()
 5     return func_02
 6 
 7 @func   #func_1=func(func_1)
 8 def func_1():
 9     print("已经实现的功能")
10 if "__name__" == "__main__":
11     func_1()

装饰器原理:

调用被装饰的函数:

流程:@func就相当于func(func_1),所以就是调用func()函数,然后return func_02(返回func_02也就是相当于调用func_02()),那么会先打印print("新功能"),然后接下来再调用fu()函数(也就是func_1()函数),然后就是打印print("已经实现的功能"),然后就结束了。

3)装饰器:装饰类

 1 def func(fu):  #外层函数的第一个参数类型为函数
 2     def func_02():
 3         print("新功能")
 4         return fu()    #这里记得要加return ,要不然你下面 t=func_1() 返回就是一个None了,这里就是一个坑
 5     return func_02
 6 
 7 @func   #func_1=func(func_1)
 8 class func_1():
 9     def __init__(self):
10         print("已经实现的功能")
11 
12 t=func_1()
13 print(t)

4)装饰器:带固定参装饰器

 1 def func(fu):  #外层函数的第一个参数类型为函数
 2     def func_02(a,b):     #这里记得也要传入参数,要不然会报错
 3         print("新功能")
 4         fu(a,b)       #这里记得也要传入参数,要不然会报错
 5     return func_02
 6 
 7 @func   #func_1=func(func_1)
 8 def func_1(a,b):
 9         print("a+b",a+b)
10 
11 func_1(1,2)

5)装饰器:通用装饰器

 1 def func(fu):  #外层函数的第一个参数类型为函数
 2     def func_02(*args,**kwargs):
 3         print("新功能")
 4         fu(*args,**kwargs)
 5     return func_02
 6 
 7 @func   #func_1=func(func_1)
 8 def func_1():                      #你这里可以传入单个参数或者多个参数都可以
 9     print("a+b")
10 
11 func_1()

2.类装饰器(__call__)

1)类的装饰器写法, 不带参数(先通过构造函数__init __()传入函数;再通过__call __方法重载,并返回一个函数。)

 1 class func_02():
 2     def __init__(self, func):
 3         self.func = func
 4     def __call__(self, *args, **kwargs):
 5         print({} is running.format(self.func.__name__))
 6         return self.func(*args, **kwargs)
 7 
 8 @func_02
 9 def func_1():
10         print("运行成功")
11 
12 func_1()

2)类的装饰器写法, 带参数(先通过构造函数__init __()传入装饰器参数;再通过__call __方法传入被装饰的函数,并返回一个函数)

 1 class func_02():
 2     def __init__(self, code):  
 3         self.code = code
 4     def __call__(self, func):
 5         def func_03(*args, **kwargs):
 6             print({} is running.format(func.__name__))
 7             print(Code: {}.format(self.code))
 8             return func(*args, **kwargs)    # 正式调用主要处理函数
 9         return func_03
10 
11 @func_02(code="123")    #传入参数
12 def func_1():
13     print("运行成功")
14 
15 func_1()

五.面试问题

1.请列举装饰器两种实现方式                    --------> 闭包函数、类中定义的__call__方法

2.装饰器可以装饰类吗                               --------> 可以

3.类可以当装饰器吗                                   --------> 可以

4.如何实现通用装饰器                               ---------> 传参使用不定长参数

5.可以同时被多个装饰器装饰吗                ---------> 可以

六.应用场景

1.可以再外层函数加上时间计算函数,计算函数运行时间。

2.计算函数运行次数。

3.可以用在框架的路由参数上。

4.插入日志,作为函数的运行日志。

5.事务处理,可以让函数实现事务的一致性,让函数要么一起运行成功,要么一起运行失败。

6.缓存,实现缓存处理。

7.权限的校验,在函数外层套上权限验证的代码,实现权限校验。

8.登录校验

 1 def login(func):  #外层函数的第一个参数类型为函数
 2     def func_02():
 3         name=input("请输入用户名:")
 4         pwd=input("请输入密码:")
 5         if name=="admin" and pwd==1:
 6             func()
 7         else:
 8             print("用户名或密码错误,请重新登录")
 9     return func_02
10 
11 @login   #func_1=login(func_1)
12 def func_1():
13         print("登录成功,欢迎您")
14 
15 func_1()

 

原文:https://www.cnblogs.com/hao2018/p/11411555.html

评论(0
© 2014 bubuko.com 版权所有 - 联系我们:wmxa8@hotmail.com
打开技术之扣,分享程序人生!