Python - 装饰器及有参
装饰器
初始
开放封闭原则:
扩展是开放的(增加新功能)
修改源码是封闭(修改已经实现的功能)
在不改变源代码及调用方式的基础下额外增加新的功能
装饰器:用来装饰的工具
标准版(装饰器):
def func(a): #a是要被装饰的函数名
def foo(*args,**kwargs):
"装饰之前的操作"
ret = a(*args,**kwargs)
"装饰之后的操作"
return ret
return foo
@func
def f1(*args,**kwargs):
print(f"这是一个{args}")
return "我可以返回了"
f1(1,2,3,34,4,5)
语法糖 -- 甜
语法糖必须放在被装饰的函数正上方
有参装饰器
带参数的装饰器
def startEnd(fun):
def wraper(name):
print("!!!!!!!!!!!!start!!!!!!!!!")
fun(name)
print("!!!!!!!!!!!!!end!!!!!!!!!")
return wraper
返回值是wraper函数
hello()相当于执行wraper()
@startEnd
def hello(name):
print("hello {0}".format(name))
hello("boy")
在不改变代码的情况下,给现有的函数增加新的功能
装饰器通过@进行使用,相当于把hello()函数作为参数
@startEnd 相当于 hello = startEnd(hello())
当调用hello()的时候,就相当于调用了startEnd(hello())
装饰器其实就是要你的内存地址
重新给你封装新的内存 地址。
你执行的时候是执行新的内存地址
a = hello
a() 相当于hello()
a = startEnd(hello)
a = hello 核心
def author(mm):
def hello(fun):
def preHello(name):
print("This author is {0}".format(mm))
print("###########start################")
fun(name)
print("############end#################")
return preHello
return hello
@author("aaa") #装饰器最外面的一个传入的参数
def cs(name): #装饰器传入的函数,中间那个
print("welcome {0}".format(name))
xx = author("chen")(cs)
xx("aaaavvvvv")
cs("ffffffff") #装饰器最里面传入的
多个装饰器装饰一个函数
def wrapper1(func):
def inner1(*args,**kwargs):
print(1)
func(*args,**kwargs)
print(11)
return inner1
def wrapper2(func): # func == foo
def inner2(*args,**kwargs):
func(*args, **kwargs)
print(22)
return inner2
def wrapper3(func):
def inner3(*args,**kwargs):
print(3)
func(*args, **kwargs)
print(33)
return inner3
@wrapper1 # 1 11
@wrapper3 # 3 33
@wrapper2 # 8 22
def foo():
print(8)
foo = wrapper2(foo) # foo == inner2
foo = wrapper3(foo) # inner3 = wrapper3(inner2)
foo = wrapper1(foo) # inner1 = wrapper1(inner3)
foo() # inner1()
foo = wrapper3(foo) # foo == inner3
foo = wrapper2(foo) # foo = wrapper2(inner3) foo == inner2
foo = wrapper1(foo) # foo = wrapper1(inner2)
被装饰的函数正上方有多个装饰器,先执行离被装饰函数最近的装饰器
先执行离被装饰的函数最近的语法糖
小技巧:进入装饰器从上往下,走到最会一个装饰器执行被装饰的函数,退出装饰器从下往上走