自己编写一个装饰器中的装饰器函数
Posted 先完成一个小目标
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了自己编写一个装饰器中的装饰器函数相关的知识,希望对你有一定的参考价值。
看了“大道曙光”的《探究functools模块wraps装饰器的用途》的文章。基本上弄清了wraps的工作原理,为了检验一下自己理解的程度,于是动手写一个类似的 wraps函数,请大家指教。
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#filename : mywrapper.py
#date: 2017-06-02
‘‘‘ wrapper function by my code.‘‘‘
import functools
import sys
WAPPER_ASSIGNMENTS = (‘__module__‘,‘__name__‘,‘__qualname__‘,
‘__doc__‘,‘__annotations__‘)
WAPPER_UPDATES = (‘__dict__‘,)
def mywrapper_update(wrapper,
wrapped,
assigned = WAPPER_ASSIGNMENTS,
updated = WAPPER_UPDATES):
‘‘‘ wrapper 闭合函数
wrapped 被调用函数‘‘‘
#将 WAPPER_ASSIGNMENT 元组中的属性 从被调用函数复制到闭合函数
for x in assigned:
try:
value = getattr(wrapped,x)
except:
pass
else:
setattr(wrapper,x,value)
# 从被调用函数字典内容更新到闭合函数
for x in updated:
getattr(wrapper,x).update(getattr(wrapped,x))
wrapper.__wrapped__ = wrapped #被调用函数的原始保存,help(add.__wrapped__) 可测试对比
return wrapper
def mywraps(wrapped,
assigned = WAPPER_ASSIGNMENTS,
updated = WAPPER_UPDATES):
def callf(func):
return mywrapper_update(func,wrapped,assigned,updated)
return callf
#================测试===================
debug_log = sys.stderr
def trace(func):
if debug_log :
@mywraps(func) #把被调用函数当作装饰器函数的参数
def callfile(*args,**kwargs): # callfile 成了装饰器函数的被调用函数
debug_log.write(‘function name:{}\n‘.format(func.__name__))
debug_log.write(‘function args:{}\n‘.format(args))
debug_log.write(‘callfile name:{}\n‘.format(callfile.__name__))
res = func(*args,**kwargs)
return res
return callfile
else:
return func
@trace
def add(x,y):
‘‘‘ return x+y ‘‘‘
return x+y
print add(5,6)
print ‘func name:‘,add.__name__
help (add)
help(add.__wrapped__)
#=========运行结果=====================
function name:add
function args:(5, 6)
callfile name:add
11
func name: add
Help on function add in module __main__:
add(*args, **kwargs)
return x+y
Help on function add in module __main__:
add(x, y)
return x+y
个人理解总结:mywraps 的作用就是装饰器中的装饰器,通过在装饰器中把func的一系列属性复制给callf,来达到在调用被装饰过的add函数时,add 的属性还是原来属性。
以上是关于自己编写一个装饰器中的装饰器函数的主要内容,如果未能解决你的问题,请参考以下文章