本文来自投稿,不代表Linux运维部落立场,如若转载,请注明出处:http://www.178linux.com/88032
python装饰器
装饰器本质是一个装饰器函数,在不改变一个函数的函数体本身的情况下,实现函数体本身外其他的功能
1.实现一个装饰器
def logger(fn): #装饰器函数必须只能传入一个参数,那就是被装饰函数
print(‘in’)
def wrapper(*args,**kwargs):
print(‘before’)
ret = fn(*args,**kwargs)
print(‘after’)
return ret
return wrapper
@logger
def foo3(x=3,y=4): #相当于 foo3=logger(foo3)
”’i’m foo3”’
print(x,y)
代码在加载时就会打印 ‘in’
执行foo3函数相当于执行下面的函数 执行foo3(参数) ,args 和kwargs会获取实际输入的位置参数和关键字参数,然后传给原函数中调用(它不会获取原函数中的默认参数值,但这不会改变函数执行结果).
def wrapper(*args,**kwargs):
print(‘before’)
ret = foo3(*args,**kwargs)
print(‘after’)
return ret
2.文档字符串 和 带参数的装饰器
一个函数定义之后就会有对应的文档字符(.__doc__)等属性生成. 装饰器函数包装过后,获取不到原函数的各种属性就变成了wrapper对应的属性
下面使用了一个带有参数的装饰器把wrapper 函数装饰成一个新的wrapper函数,这里使用到了一个带有参数的装饰器
代码2.1:
def copy_properties(src):
def _copy(dst):
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
return dst
return _copy
def logger(fn):
@copy_properties(fn) # wrapper = wrapper(fn)(wrapper)
def wrapper(*args,**kwargs):
‘I am wrapper’
print(‘begin’)
x = fn(*args,**kwargs)
print(‘end’)
return x
return wrapper
@logger #add = logger(add)
def add(x,y):
”’This is a function for add”’
return x + y
print(“name={}, doc={}”.format(add.__name__, add.__doc__))
代码2.2:
def copy_property(src):
def _copy(dst):
print(11)
dst.__name__ = src.__name__
dst.__doc__ = src.__doc__
return dst
return _copy
def add(x,y):
”’i am add”’
print(x,y)
return x+y
@copy_property(add)
def wrapper(*args,**kwargs): #wrapper = cop_property(add) (wrapper)
”’i am wrapper”’
print(22)
ret = add(*args,**kwargs)
return ret
print(add.__name__,add.__doc__)
print(wrapper.__name__,wrapper.__doc__)
运行代码2.2 会加载装饰器 运行右边的 wrapper = cop_property(add) (wrapper) 程序 ,add的属性会赋给 wrapper,打印如下.
11 如果执行wrapper(2,3) 会 先打印 22,然后执行add中的过程
add i am add
add i am add
3.对一个函数使用多个装饰器
def decorator1(func):
print(11)
def wrapper1(*args,**kwargs):
print(‘hello python 之前’)
ret=func(*args,**kwargs)
return ret
return wrapper1
def decorator2(func):
print(22)
def wrapper2(*args,**kwargs):
print(‘hello python 之后’)
ret=func(*args,**kwargs)
return ret
return wrapper2
@decorator1
@decorator2
def test(x,y):
print(‘hello python!’,x,y)
test(4,5)
22 对一个函数执行多个装饰器,执行结果相当于对decorator2装饰test的函数 再使用decorator1装饰它
11
hello python 之前
hello python 之后
hello python! 4 5
赞 (0)