Python-装饰器 decorators
1. 在函数中返回函数
def hi(name="tl"):def greet():return "now you are in the greet() function"def welcome():return "now you are in the welcome() function"if name == "tl":return greetelse:return welcomea = hi()print(a)print(a())# <function hi.<locals>.greet at 0x00000264BDCAA0D0># now you are in the greet() function
注意:在返回的时候返回函数名welcome而非welcome(),否则会返回函数的返回值
2. 将函数作为参数传递
def hi():return "hi tl"def doSomeThingBeforeHi(func):print("Im in front of Hi!")print(func())doSomeThingBeforeHi(hi)# Im in front of Hi!# hi tl
可以看到传递进去了hi()
3. 装饰器
3.1 第一个装饰器
使用装饰器,可以在一个函数的前后执行代码
def a_new_decorator(a_func):def wrapTheFunction():print("I am doing some boring work before executing a_func()")a_func()print("I am doing some boring work after executing a_func()")return wrapTheFunctiondef a_function_requring_decoration():print("I am the function which needs some decoration to remove my foul smell")a_function_requring_decoration()a_function_requring_decoration = a_new_decorator(a_function_requring_decoration)a_function_requring_decoration()# I am the function which needs some decoration to remove my foul smell# I am doing some boring work before executing a_func()# I am the function which needs some decoration to remove my foul smell# I am doing some boring work after executing a_func()
3.2 使用’@‘来生成一个装饰器
def a_new_decorator(a_func):def wrapTheFunction():print("I am doing some boring work before executing a_func()")a_func()print("I am doing some boring work after executing a_func()")return wrapTheFunction@a_new_decoratordef a_function_requring_decoration():print("I am the function which needs some decoration to remove my foul smell")a_function_requring_decoration()
@a_new_decorator其实和a_function_requring_decoration = a_new_decorator(a_function_requring_decoration)是相同意思
3.3 装饰器的方法名
按照3.2的方法构建装饰器后,如果我们打印方法名,会出现如下问题:
print(a_function_requring_decoration.__name__)# wrapTheFunction
这里的函数被warpTheFunction替代了。它重写了我们函数的名字和注释文档(docstring)。我们可以使用functools.wraps解决这一问题
from functools import wrapsdef a_new_decorator(a_func):@wraps(a_func)def wrapTheFunction():print("I am doing some boring work before executing a_func()")a_func()print("I am doing some boring work after executing a_func()")return wrapTheFunction@a_new_decoratordef a_function_requiring_decoration():print("I am the function which needs some decoration to ""remove my foul smell")print(a_function_requiring_decoration.__name__)# a_function_requiring_decoration
3.4 装饰器蓝本规范
from functools import wrapsdef decorator_name(f):@wraps(f)def decorated(*args, **kwargs):if not can_run:return "Function will not run"else:return f(*args, **kwargs)return decorated@decorator_namedef func():return("Function is running")can_run = Trueprint(func())can_run = Falseprint(func())
4. 类装饰器
class decorator_class(object):def __init__(self, func):self._func = funcprint("class decorator initing")def __call__(self):print("class decorator running")self._func()print("class decorator ending")@decorator_classdef func():print("function!")print("----------------------")func()# class decorator initing# ----------------------# class decorator running# function!# class decorator ending
