python装饰器不改变原函数属性,带参装饰器
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))
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律