首页 > 代码库 > 自己编写一个装饰器中的装饰器函数

自己编写一个装饰器中的装饰器函数

看了“大道曙光”的《探究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 = http://www.mamicode.com/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 的属性还是原来属性。

自己编写一个装饰器中的装饰器函数