首页 > 代码库 > python学习-装饰器
python学习-装饰器
参考:
http://www.wklken.me/posts/2013/07/19/python-translate-decorator.html
http://www.cnblogs.com/wupeiqi/articles/4980620.html
一、装饰器必备知识
1、函数可以被赋值给一个变量
def show(msg): print(msg)# 调用 show 函数show("这是调用 show() 的输出")# 将函数 show 赋值给 foofoo = show# 调用 foofoo("这是调用 foo() 的输出")# 删除 f1 函数后再次调用 f2del showfoo("这是删除 show() 之后条用 foo() 的输出")###########输出结果这是调用 show() 的输出这是调用 foo() 的输出这是删除 show() 之后条用 foo() 的输出
2、函数可以被重新定义
def show(): print("第一次定义 show")def show(): print("第二次定义 show")# 函数的输出会是:第二次定义 showshow()
3、函数的函数体里面也可以再定义函数,并且在函数体里面可以立即被调用
def show(): def foo(): return "WenChong" print(foo())
4、函数的返回结果也可以是函数
def run(action=‘remove‘): def remove_user(): return "del user name" def add_user(): return "add user name" if action == ‘remove‘: return remove_user else: return add_user# 将 run() 函数的返回值赋值给 actionaction = run(action=‘add‘)# 输出 action 的值会是一个函数对象print(action)# 在 action 后面加上 () ,会将 add_user() 函数的返回值输出print(action())# 也可以直接这样输出print(run(action=‘add‘)())#######输出结果<function run.<locals>.add_user at 0x10ce16840>add user nameadd user name
5、函数也可以作为一个参数传递给函数
def show(): return "WenChong"def foo(func): msg = func() print(msg)# 将函数 show 作为变量传递给 foo 函数foo(show)#######输出结果WenChong
6、动态参数
def my_func(*args,**kwargs): print(args,kwargs)
二、写一个装饰器
装饰器是以另一个函数作为参数的函数
def func_action(my_func): # 定义个一个 inner_func 函数,用户在 my_func 函数执行前后再执行其他代码 def inner_func(): print("my_func start...") # 调用 my_func 函数,记得后面一定要有() my_func() print("my_func end...") # 返回 inner_func 函数,这个函数里面包含了 my_func 函数的代码以及 my_func 前后的代码 return inner_func# 创建一个函数def my_func(): print("my_func 函数被调用")# 调用 my_func 函数my_func()######输出结果my_func 函数被调用
func_aciton 函数可以传递一个函数作为参数,并在这个参数的前后增加代码
那么就可以将 my_func 函数传递给 func_aciton 以完成对 my_func 的装饰
# 将 func_action 在赋值给一个变量 other_my_funcother_my_func = func_action(my_func)# 调用 other_my_func 函数other_my_func()######输出结果my_func start...my_func 函数被调用my_func end...
这样每次每次想在某个函数的前后增加代码的时候都可以通过 func_aciton 重新赋值给另外一个变量,并执行。
三、使用装饰器
通过上面的例子使用装饰器过于麻烦,需要定义另一个变量,然后再调用这个变量,python 提供了特殊的语法,在函数的上面使用 @func_action 添加装饰器
@func_actiondef my_func(): print("my_func 函数被调用")# 调用 my_func 函数my_func()#####输出结果my_func start...my_func 函数被调用my_func end...
@ 符号的作用:
1、将@符号下面的函数作为参数传递给@符号后面的函数,并执行
2、将返回的结果再重新赋值给@符号下面的函数
四、向装饰器函数传递参数以及获取返回值
当被装饰的函数有参数时,可以通过动态参数的方式来给被装饰的参数传递参数
当被装饰的函数有返回值时,可以通过捕获 func 的返回值通过 inner_func 返回
def func_action(func): # 传递参数给别装饰的函数 def inner_func(*args,**kwargs): print("func start...") # 获取被装饰函数的返回值 ret = func(*args,**kwargs) print("func end...") # 将被装饰函数的返回值返回给 inner_func return ret return inner_func
五、向装饰器传递参数
装饰器是一个以函数为参数的函数,那么如果需要向装饰器传递参数时,需要声明一个用于创建装饰的函数
# 声明创建装饰器的函数def decorator_maker(msg1,msg2): print("decorator start make...",msg1) # 真正的装饰器 def my_decorator(func): def inner(*args,**kwargs): print(‘func run start...‘) ret = func(*args,**kwargs) print(‘func run end...‘) return ret return inner print("decorator end make...",msg2) return my_decorator@decorator_maker(‘Wen‘,‘Chong‘)def show(msg): print(msg) return msg# 调用被装饰过后的函数 show(‘aaaa‘)
输出结果:
decorator start make... Wendecorator end make... Chongfunc run start...aaaafunc run end...
一个可以处理任何参数的装饰器代码片段
# 装饰 装饰器 的装饰器 (好绕.....)def decorator_with_args(decorator_to_enhance): """ 这个函数将作为装饰器使用 它必须装饰另一个函数 它将允许任何接收任意数量参数的装饰器 方便你每次查询如何实现 """ # 同样的技巧传递参数 def decorator_maker(*args, **kwargs): # 创建一个只接收函数的装饰器 # 但是这里保存了从创建者传递过来的的参数 def decorator_wrapper(func): # 我们返回原始装饰器的结果 # 这是一个普通的函数,返回值是另一个函数 # 陷阱:装饰器必须有这个特殊的签名,否则不会生效 return decorator_to_enhance(func, *args, **kwargs) return decorator_wrapper return decorator_maker
python学习-装饰器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。