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


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

  • 相关阅读:
    C#获取网上图片的宽高代码
    发现两个有趣的CSS3效果
    .NET WinForm画树叶小程序
    生产环境使用 pt-table-checksum 检查MySQL数据一致性【转】
    awk入门【转】
    MySQL数据库之auto_increment【转】
    crontab的使用方法
    linux添加swap分区【转】
    nginx反向代理转发后页面上的js css文件无法加载【原创】
    Serv-U日志文件保存设置【转】
  • 原文地址:https://www.cnblogs.com/killad/p/6937085.html
Copyright © 2020-2023  润新知