zoukankan      html  css  js  c++  java
  • 自己编写一个装饰器中的装饰器函数

    看了“大道曙光”的《探究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:{} '.format(func.__name__))
                 debug_log.write('function args:{} '.format(args))
                 debug_log.write('callfile name:{} '.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 的属性还是原来属性。

  • 相关阅读:
    Linux文本检索命令grep笔记
    Linux文本检索命令grep笔记
    Linux文件查询笔记
    Linux文件查询笔记
    Linux文件默认权限和umask笔记
    Linux文件默认权限和umask笔记
    Linux关于文件的权限笔记
    Linux关于文件的权限笔记
    Linux文件操作实用笔记
    6.创建自定义菜单
  • 原文地址:https://www.cnblogs.com/killad/p/6937085.html
Copyright © 2011-2022 走看看