匿名函数
1)匿名函数有个限制,就是只能有一个表达式,不用写return,返回值就是该表达式的结果。
2)因为没有名字,不必担心函数名冲突
3)可以把匿名函数赋值给一个变量,再利用变量来调用该函数
4)同样,也可以把匿名函数作为返回值返回,比如:
def build(x, y):
return lambda: x * x + y * y
装饰器
1)函数对象有一个__name__属性,可以拿到函数的名字
2)这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),decorator就是一个返回函数的高阶函数
def log(func):
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
观察上面的log,因为它是一个decorator,所以接受一个函数作为参数,并返回一个函数。我们要借助Python的@语法,把decorator置于函数的定义处:
@log
def now():
print('2015-3-25')
调用now()函数,不仅会运行now()函数本身,还会在运行now()函数前打印一行日志:
>>> now()
call now():
2015-3-25
把@log放到now()函数的定义处,相当于执行了语句:
now= log(now)如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:
def log(text):
def decorator(func):
def wrapper(*args, **kw):
print('%s %s():' % (text, func.__name__))
return func(*args, **kw)
return wrapper
return decorator
这个3层嵌套的decorator用法如下:
@log('execute')
def now():
print('2015-3-25')
执行结果如下:
>>> now()
execute now():
2015-3-25
和两层嵌套的decorator相比,3层嵌套的效果是这样的:
>>> now = log('execute')(now)
首先执行log('execute'),返回的是decorator函数,再调用返回的函数,参数是now函数,返回值最终是wrapper函数。
3)因为返回的那个wrapper()函数名字就是'wrapper',所以,需要把原始函数的__name__等属性复制到wrapper()函数中,否则,有些依赖函数签名的代码执行就会出错。
即在总的编写前加上:
import functools
在wrapper定义前加上:
@functools.wraps(func)
使用时在案例代码上进行修改可以简单得到想要的效果
自己打一遍理解起来更快