写在前面:
python装饰器是修改其他函数的功能的函数,有助于让我们的代码更简短。
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。
在 Python 中我们可以在一个函数中定义另一个函数:
def hi(name="yasoob"):
print("now you are inside the hi() function")
def greet():
return "now you are in the greet() function"
def welcome():
return "now you are in the welcome() function"
print(greet())
print(welcome())
print("now you are back in the hi() function")
hi()
#output:now you are inside the hi() function
# now you are in the greet() function
# now you are in the welcome() function
# now you are back in the hi() function
# 上面展示了无论何时你调用hi(), greet()和welcome()将会同时被调用。 然后greet()和welcome()函数在hi()函数之外是不能访问的,比如:
greet()
#outputs: NameError: name 'greet' is not defined
从函数中返回函数其实并不需要在一个函数里去执行另一个函数,我们也可以将其作为输出返回出来:
def hi(name="yasoob"):
def greet():
return "now you are in the greet() function"
def welcome():
return "now you are in the welcome() function"
if name == "yasoob":
return greet
else:
return welcome
a = hi()
print(a)
#outputs:
#上面清晰地展示了`a`现在指向到hi()函数中的greet()函数
#现在试试这个
print(a())
#outputs: now you are in the greet() function
def hi():
return "hi yasoob!"
def doSomethingBeforeHi(func):
print("I am doing some boring work before executing hi()")
print(func())
doSomethingBeforeHi(hi)
#outputs:I am doing some boring work before executing hi()
# hi yasoob!
装饰器让你在一个函数的前后去执行代码。
在上一个例子里,其实我们已经创建了一个装饰器,现在我们修改下上一个装饰器:
def use_logging(func ) :
def wrapper(*args,**kwargs):
logging.warn("%s is running” % func._name__)return func(*args,**kwargs)
return wrapper
def bar():
print( 'i am bar ' )
bar = use_logging(bar)
bar()
函数use_logging就是装饰器,它把执行真正业务方法的func包裹在函数里面,看起来像bar被use_ logging装饰了。
@符号是装饰器的语法糖,在定义函数的时候使用,避免再一次赋值操作。
def use_logging(func) :
def wrapper(*args,**kwargs):
logging.warn( "%s is running” % func._name_)return func(*args)
return wrapper
@use_logging
def foo( ):
print( "i am foo")
@use_logging
def bar():
print("i am bar")
bar()
如上所示,这样我们就可以省去bar = use_logging(bar)这一句了,直接调用bar()即可得到想要的结果。概括的讲,装饰器的作用就是为已经存在的函数或对象添加额外的功能。
[1]https://www.runoob.com/w3cnote/python-func-decorators.html
[2]https://www.zhihu.com/question/26930016
[3]https://www.cnblogs.com/tobyqin/p/python-decorator.html