python 装饰器

在代码运行期间动态增加功能的方式,叫装饰器docorator

docorator 就是一个返回函数的高阶函数

 

# _*_ coding:utf-8 _*_
import functools
import time


# 编写装饰函数,在函数执行之前打印 call func.__name__
def log(func):#func是传入的函数,要执行的函数
@functools.wraps(func)#加这行是为了使返回的函数名变成func.__name__,不加这行的话返回的函数名是 wrapper.__name__
def wrapper(*args, **kw):
print('call %s():' % func.__name__)#在函数执行之前打印‘call func.__name__’
return func(*args, **kw)#执行func函数

return wrapper


@log #在装饰函数之前加一个@来调用装饰函数,写在定义的函数now()的前面,那么在执行now()之前会先执行log()这个装饰函数
def now():
print('2015-3-25')


f = now
f()#调用now函数,相当于执行了语句 now= log(now)
print(f.__name__)

#如果docorator本身需要传入参数,函数如下,有3层的嵌套
def log(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)

return wrapper

return decorator


@log('execute')
def now1():
print('2018-01-12')


f1 = now1
f1()
print(f1.__name__)


# 请设计一个decorator,它可作用于任何函数上,并打印该函数的执行时间:
def metric(fn):
@functools.wraps(fn)
def wrapper(*args, **kw):
start = time.time()
result = fn(*args, **kw)
end = time.time()
print('%s executed in %.2fs ms' % (fn.__name__, (end - start) * 1000))
return result

return wrapper


@metric
def now2(x, y):
time.sleep(1)
return (x + y)


f = now2(10, 20)
if f == 30:
print('pass')
else:
print('failed')


# 请编写一个decorator,能在函数调用的前后打印出'begin call'和'end call'的日志
def printBeginEndCall(fn):
@functools.wraps(fn)
def wrapper(*args, **kw):
print('begin call')
result = fn(*args, **kw)
print('%s() is executed at %s' % (fn.__name__, time.asctime(time.localtime())))
print('end call')
return result

return wrapper


@printBeginEndCall
def fast(num):
return (num ** 2)


i = fast(3)
print(i)

#编写一个装饰函数,同时支持@log和@log(text)
#这个代码存在问题,但是我不知道为什么
def log(t):
if isinstance(t, str):
def decorator(fn):
@functools.wraps(fn)
def wrapper(*args, **kw):
print('%s %s()' % (t, fn.__name__))
return fn(*args, **kw)

return wrapper

return decorator

else:
@functools.wraps(t)
def wrapper(*args, **kw):
print('%s() is executed' % t.__name__)
return t(*args, **kw)

return wrapper


@log('start executing')
def test(x):
return x ** 3


f = test(6)
print(f)


@log()
def test2(y):
return (y ** 3)


f1 = test2(10)
print(f1)

posted on 2018-01-12 19:47  永恒自由森林  阅读(321)  评论(0编辑  收藏  举报

导航