ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python装饰器不改变原函数属性,带参装饰器

2020-09-05 17:31:30  阅读:330  来源: 互联网

标签:__ .__ return python wrapper datetime 带参 装饰 def


 

def copy_properties(src,dst): # 提供一个函数,被封装函数属性 copy 到包装函数属性,保持被封装函数属性不变
    dst.__name__=src.__name__
    dst.__doc__=src.__doc__
    dst.__qualname__=src.__qualname__

def logger(fn):
    def wrapper(*args,**kwargs):
        'i\'m wrapper'
        print('begin')
        kin=fn(*args,**kwargs)
        print('after')
        return kin
    copy_properties(fn,wrapper)
    return wrapper

@logger
def lag(x,y):
    'i\'m a function'
    return x+y
print('name={}\ndoc={}'.format(lag.__name__,lag.__doc__))

 

通过copy_properties函数将被包装函数的属性覆盖掉包装函数

凡是被装饰的函数都要复制这些属性

可以将copy_properties函数构建成装饰器函数,带参装饰器

  


import datetime,time
def copy_properties(src):
def wrapper(dst):

dst.__name__=src.__name__
dst.__doc__=src.__doc__
dst.__qualname__=src.__qualname__
return dst
return wrapper


def logger(fn):
#logger中不能直接引用copy_properties中的嵌套函数,利用copy_properties的返回值进行引用,fn实参形成闭包,等价于copy_properteis.wrapper(有闭包)
# => logger.wrapper = copy_properties.wrapper(logger.wrapper)
@copy_properties(fn)
def wrapper(*args,**kwargs):

'this is the wrapper'
print("args={},kwargs={}".format(args,kwargs))
start=datetime.datetime.now()
ret=fn(*args,**kwargs)
duration=datetime.datetime.now()-start
print('function {} took {}s'.format(fn.__name__,duration.total_seconds()))
return ret


return wrapper
@logger
def add(x,y):
'this is the function'
print('call add')
time.sleep(2)
return x+y
add(5,7)

 

 

 

import datetime,time

def logger(fn):
    def wrapper(*args,**kwargs):
        print('args={}\nkwargs={}'.format(args,kwargs))
        start=datetime.datetime.now()
        kin=fn(*args,**kwargs)
        duration=(datetime.datetime.now()-start)
        print('function {} took {} seconds'.format(fn.__name__,duration.total_seconds()))
        return kin
    return wrapper

@logger
def lag(x,y):
    time.sleep(2)
    return x+y
print(lag(5,y=8))

 

 

 

 

带参装饰器


import datetime,time
def copy_properties(src):
def wrapper(dst):
dst.__name__=src.__name__
dst.__doc__=src.__doc__
dst.__qualname__=src.__qualname__
return dst
return wrapper

def logger(t):
def _logger(fn):
@copy_properties(fn)
def wrapper(*args,**kwargs):
'i\'m a wrapper'
print('args:{}\nkwargs:{}'.format(args,kwargs))
start=datetime.datetime.now()
kin=fn(*args,**kwargs)
duration=datetime.datetime.now()-start
if duration.total_seconds()>t:
print('function {} took {} seconds'.format(fn.__name__,duration.total_seconds()))
return kin
return wrapper
return _logger
@logger(2)
def lag(x,y):
'i\'m a function'
time.sleep(2)
return x+y
print(lag.__name__,lag.__doc__,lag.__qualname__)
print(lag(5,y=9))
 

 

def kin(fn):
    return 10
@kin
def hip(x,y):
    return x+y
hip

hip 本来指向一个函数对象,但经过装饰后,指向int 10

def kin(fn):
    return kin
@kin
def hip(x,y):
    return x+y
hip(50)

hip经过装饰后,指向了装饰器函数本身

 

import datetime,time

def copy_properties(src):
    def wrapper(dst):
        dst.__name__=src.__name__
        dst.__doc__=src.__doc__
        dst.__qualname__=src.__qualname__
        return dst
    return wrapper

def logger(duration,func=lambda duration,name:print('{} took {} seconds'.format(name,duration))):
    def _logger(fn):
        def wrapper(*args,**kwargs):
            start=datetime.datetime.now()
            kin=fn(*args,**kwargs)
            delta=(datetime.datetime.now()-start).total_seconds()
            if delta>duration:
                func(delta,fn.__name__)
            return kin
        return wrapper
    return _logger

@logger(3)
def hip(x,y):
    time.sleep(3)
    return x+y
print(hip(5,y=6))

 

标签:__,.__,return,python,wrapper,datetime,带参,装饰,def
来源: https://www.cnblogs.com/dissipate/p/13618915.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有