2023年6月29日发(作者:)
Python中编写带参数decorator考察上⼀节的 @log 装饰器:def log(f): def fn(x): print 'call ' + f.__name__ + '()...' return f(x) return fn发现对于被装饰的函数,log打印的语句是不能变的(除了函数名)。如果有的函数⾮常重要,希望打印出'[INFO] call xxx()...',有的函数不太重要,希望打印出'[DEBUG] call xxx()...',这时,log函数本⾝就需要传⼊'INFO'或'DEBUG'这样的参数,类似这样:@log('DEBUG')def my_func(): pass把上⾯的定义翻译成⾼阶函数的调⽤,就是:my_func = log('DEBUG')(my_func)上⾯的语句看上去还是⽐较绕,再展开⼀下:log_decorator = log('DEBUG')my_func = log_decorator(my_func)上⾯的语句⼜相当于:log_decorator = log('DEBUG')@log_decoratordef my_func(): pass所以,带参数的log函数⾸先返回⼀个decorator函数,再让这个decorator函数接收my_func并返回新函数:def log(prefix): def log_decorator(f): def wrapper(*args, **kw): print '[%s] %s()...' % (prefix, f.__name__) return f(*args, **kw) return wrapper return log_decorator@log('DEBUG')def test(): passprint test()执⾏结果:[DEBUG] test()...None对于这种3层嵌套的decorator定义,你可以先把它拆开:# 标准decorator:def log_decorator(f): def wrapper(*args, **kw): print '[%s] %s()...' % (prefix, f.__name__) return f(*args, **kw) return wrapperreturn log_decorator# 返回decorator:def log(prefix): return log_decorator(f)拆开以后会发现,调⽤会失败,因为在3层嵌套的decorator定义中,最内层的wrapper引⽤了最外层的参数prefix,所以,把⼀个闭包拆成普通的函数调⽤会⽐较困难。不⽀持闭包的编程语⾔要实现同样的功能就需要更多的代码。实例1. 给 @performace 增加⼀个参数,允许传⼊'s'或'ms':@performance('ms')def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1))import timedef performance(unit): def perf_decorator(f): def wrapper(*args, **kw): t1 = () r = f(*args, **kw) t2 = () t = (t2 - t1) * 1000 if unit=='ms' else (t2 - t1) print ('call %s() in %f %s' % (f.__name__, t, unit)) return r return wrapper return perf_decorator@performance('ms')def factorial(n): return reduce(lambda x,y: x*y, range(1, n+1))print (factorial(10))#输出结果call factorial() in 4.497051 ms3628800
发布者:admin,转转请注明出处:http://www.yc00.com/news/1687977447a62865.html
评论列表(0条)