[python]返回函数和装饰器
2019-04-08 本文已影响0人
喵吉呀呀
返回函数
返回函数: 函数作为结果返回
e.g:
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
f = lazy_sum(1,2) # 调用lazy_sum并传参,实质是把sum赋值给f
f() # 调用
# 这两行相当于lazy_sum(1,2)()
3
>每次调用都会返回一个新的函数,即使传入相同的参数:
f1 = lazy_sum(1, 3, 5, 7, 9)
f2 = lazy_sum(1, 3, 5, 7, 9)
f1==f2
>>>False
装饰器(decorator)
补充知识:
函数对象有一个name属性
e.g:
def now():
print('2015-3-25')
f = now
now.__name__
>>>'now'
f.__name__
>>>'now'
装饰器写法:
@funcName
e.g:
def print_caller(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
def test():
print('test')
@print_caller
test()
>>>call test():
>>>test
decorator实质是返回一个函数,所以,原来的test()函数仍然存在,只是现在同名的test变量指向了新的函数,于是调用test()将执行新函数,即在print_caller()函数中返回的wrapper()函数。
wrapper()函数的参数定义是(*args, **kw),因此,wrapper()函数可以接受任意参数的调用。在wrapper()函数内,首先打印日志,再紧接着调用原始函数。
所以,@print_caller相当于执行了:
test = print_caller(test)
打印函数执行前后时间的example:
def metric(func):
def decorator(*args, **kw):
print('start:%s' % int(time.time()))
time.sleep(2)
r = func(args, **kw)
print('end:%s' % int(time.time()))
return r
return decorator
@metric
def test(a):
print('test')
test()
>>>start:1554695731
>>>test
>>>end:1554695733
上述几个例子都是decorator不需传参数的情况,如果decorator需要传参数,就需要编写一个返回decorator的高阶函数
e.g:
def add_text(text):
def decorator(func):
def wrapper(*args, **kw):
print('text:%s' % text)
r = func(args, **kw)
return r
return wrapper
return decorator
@add_text('miao')
def test(a):
print('test')
>>>text:miao
>>>test
实质是三层的嵌套,@add_text相当于执行了:
test = add_text('miao')(test)
*decorator本质的嵌套返回函数,会导致原型指针发生变化,name等属性也随之发生变化,如上述的name会从test变成wrapper,理论上应该添加一句wrapper.name = func.name,把原型指针指针原函数,但Python存在内置的functools.wraps做了这个处理
import functools
# 不带参数的装饰器
def print_caller(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
# 带参数的装饰器
def add_text(text):
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('text:%s' % text)
r = func(args, **kw)
return r
return wrapper
return decorator