码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-06-03 15:03:25      阅读:252      评论:0      收藏:0      [点我收藏+]

标签:odi   wrap   int   ssi   main   back   cti   nts   port   

看了“大道曙光”的《探究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 的属性还是原来属性。

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

标签:odi   wrap   int   ssi   main   back   cti   nts   port   

原文地址:http://www.cnblogs.com/killad/p/6937085.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!