一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第8天
装饰器
装饰器是程序开发中经常会用到的一个功能,用好了装饰器,开发效率会如虎添翼,所以这也是python面试中必问的题,但对于好多初次接触这个功能的人而言,这个功能很难理解。
- 先明白这段代码
def foo():
print('foo')
foo #表示函数
foo() #表示调用函数
>>>>>>>>>>>> 以上是之前学过的,都应该能理解
def foo():
print('foo')
foo = lambda x: x+1
foo() #执行lambda表示式,而不是foo函数,因为此时foo已经指向另一个匿名函数了
注意:函数名只是个变量,它指向你原来定义的那个函数,如果给函数名赋予其他的值,那么函数的功能就会改成你所赋予的那个值
需求
若一个项目已经有了底层基础的代码可以实现基础功能,此时我们还要加一个新功能(例如:验证功能),我们就要遵循封闭开放原则,这时我们就需要用到装饰器
- 封闭:对于以实现功能的代码块
- 开放:对于拓展开发
以上意思就是我们不能在原有的代码块上进行修改,我们得保证原有功能代码块的情况下进行拓展的添加
装饰器
通常闭包定义,@进行调用
定义
def xxx(func):
def xxx(参数,....):
...
func()
...
return xxx
return xxx
def docorators(func): #这里的参数是为了把底下的house函数拿过来
def wapper():
func() #这里是为了调用house这个函数
print('刷漆')
print('铺地板')
print('买家具')
print('精装房子')
return wapper
@docorators
def house():
print('毛坯房')
house()
>>>>>>
毛坯房
刷漆
铺地板
买家具
精装房子
注意:这里的返回值由house来接管,这一点非常重要
@装饰器名 ---> 原函数 = 装饰(原函数)
装饰器的功能
- 引入日志
- 函数执行时间统计
- 执行函数前预备处理
- 执行函数后清理功能
- 权限校验等场景
- 缓存
带参数的装饰器
def docorators(func): #这里的参数是为了把底下的house函数拿过来
def wapper(*args,**kwargs): #这里的参数实际就是传的北京,记住这里返回的是元组,所以必须拆包
func(*args**kwargs) #这里是为了调用house这个函数
print('刷漆')
print('铺地板')
print('买家具')
print('精装房子')
return wapper
@docorators
def house(address):
print('房子在{}'.format(address))
@docorators
def changfang(address,area):
print('房子在{},{}平方米'.format(address,area))
house('北京')
changfang('北京',1000)
这里的基础函数和装饰器的子函数以及调用函数的参数必须统一(因为这里的参数可能是多变的,为了实现装饰器的复用,我们可以把参数改成*args和**kwargs,然后进行拆包)
装饰器中的return
def docorators(func):
def wapper(*args,**kwargs):
a = func(*args**kwargs)
print('刷漆')
print('铺地板')
print('买家具')
print('精装房子')
return a
return wapper
@docorators
def house(address,price):
print('房子在{}'.format(address))
return price
r = house('北京',10000)
print(r)
如果装饰器所装饰的函数带有返回值,那么我们就必须让装饰器的子函数带上返回值
装饰器也能带参数
def outer(time):
def check(action):
def do():
if time < 22:
return action()
else:
return '对不起,您不具有权限'
return do
return check
@outer(23)
def play():
return '玩个游戏'
print(paly())
带参数的装饰器相当于把装饰器作为内部函数闭包