制心一处,无事不办

1.定义与原型

# 在不改变原有函数代码,且保持原函数调用方法不变的情况下,给原函数增加新的功能(或者给类增加属性和方法)
# 核心思想:用一个函数去装饰一个旧函数,造出一个新函数
# 语法规则:在原有的函数上加上@符号,装饰器会把下面的函数当作参数传递到装饰器中,@符又被称为语法糖
# 应用场景:引入日志,函数执行时间的统计,执行函数前的准备工作,执行函数后的处理工作,权限检验,缓存等场景中

# 定义外函数,接收一个函数作为参数
def outer(f):
# 定义一个内函数,并在内函数中调用了外函数的参数
def inner():
print(‘我是一个内函数1’)
f()
print(‘我是内函数2’)

  1. **return **inner_

@outer # 此处使用的#outer的语法就是把outer作为了装饰器,等同于 old = outer(old)
def old():
print(‘我是一个普通函数’)

old() # 此时的old函数是经过outer装饰器装饰过的函数

2.统计函数执行时间

import time
#定义装饰器
def runtime(f):
def inner():
start = time.perf_counter()
f()
end = time.perf_counter() - start
print(f’共用了{end}秒’)
return inner

@runtime
def func():
for i in range(1,10):
print(i,end=‘ ‘)
time.sleep(0.5)

func()

3.语法

①装饰器的嵌套

#定义装饰器
def outer(f):
def inner():
print(‘找到妹子,成功拿下微信…’)
f()
print(‘约会…’)
return inner

#第二个装饰器
def kz(f):
def inner():
print(‘rrrr’)
f()
print(‘ggg’)
return inner

@kz
@outer
def love():
print(‘聊天…’)

love()
#先使用离得近的装饰器(下面的),装饰成为一个函数,这个函数再被第二个装饰器装饰

②装饰带有参数的函数

#定义装饰器
def outer(f):
#在内函数加上一个参数即可
def inner(name):
print(f’找到{name}妹子,成功拿下微信…’)
f(name)
print(f’约会{name}…’)
return inner

@outer
def love(name):
print(f’和{name}聊天…’)
love(‘杨幂’)

③装饰带有多参数的函数

def outer(f):
#内函数的参数需要和需要装饰的函数的参数相对应
def inner(who,name,args,kwargs):
print(
‘约到妹子聊微信’**)
f(who,name,
args,kwargs)
print(
‘天色已晚,怎么办? 滚出我们五个九的直播间!’)
return **inner

@outer
def love(who,name,args,kwargs):
print(
f’{who}跟{name}畅谈人生…’)
print(
‘吃饭去了,吃了so many’,args)
print(
‘看视频’*
,kwargs)

love(‘任已虚’,‘杨幂’,‘牛肉干’,‘麻辣烫’,video = ‘快乐向前冲’)

④带有参数的装饰器

#如果你的装饰器需要有参数,那么给当前的装饰器套一个壳,用于接收装饰器的参数
def kuozhan(var):
def outer(f):
def inner1():
print(‘妹子给了你微信’)
f()
def inner2():
print(‘妹子给了你大逼兜’)
f()
#装饰器壳的参数,用于在函数内部去做流程控制
if var == ‘高富帅’:
return inner1
else:
return inner2
return outer

@kuozhan(‘臭屌丝’)
def love():
print(‘聊天’)

love()

⑤用类装饰器装饰函数

class Outer():
#魔术方法:当把该类的对象当作函数调用时,自动触发 obj()
def call(self,func):
self.func = func #把传经来的函数作为对象的成员方法
return self.inner #返回一个函数
#在定义的需要返回的新方法中,去装饰和处理
def inner(self,who):
print(‘拿到妹子的微信…’)
self.func(who)
print(‘看一场电影…’)
@Outer()
def love(who):
print(f’{who}和妹子聊天’)

love(‘旭旭宝宝’) #inner(‘旭旭宝宝’)
_print(love)
#此时的love就是属于Outer类这个对象中的inner方法_

⑥用类方法装饰函数

class Outer():
def newinner(f):
Outer.func = f
return Outer.inner
def inner():
print(‘拿到妹子微信’)
Outer.func()
print(‘看电影’)

@Outer.newinner
def love():
print(‘聊天’)
love()