查看原文:http://www.wyblog.cn/2016/11/26/python%e5%87%bd%e6%95%b0%e5%bc%8f%e7%bc%96%e7%a8%8b%e5%a4%87%e5%bf%98/本博文总结自廖雪峰老师python教程:
http://www.liaoxuefeng.com/
1.在python中,函数名其实是一个变量,它指向了函数,所以自然的,也可以用其他变量来指向函数。例如
f=abs
后,就直接能调用f(-10)
进行计算了。既然函数名是变量,那么也就可以被传入另一个函数了,def add(a,b,f):
,然后return f(a)+f(b)
。所谓的高阶函数,就是让函数的参数能够接收别的函数。
map/reduce函数。 map函数接收两个参数,第一个是函数,第二个是个Iterable对象,例如列表等。它将函数依次作用到每个对象元素,最后返回一个新的Iterable对象。 reduce函数接收同样的两个参数。它把第一个函数参数作用在两个元素上,然后再让结果继续和下一个元素作用,效果就如
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)
。filter函数。 filter用于过滤序列。它也接收两个参数,一个函数及一个序列。它将函数作用与每一个参数,然后根据返回值是True或者False决定保留还是丢弃元素。
sorted函数。 sorted函数可以接收一个key命名参数用于自定义排序。例如
sorted([36, 5, -12, 9, -21], key=abs)
,可以对绝对值排序。key参数的作用类似于map,同时,还可以接收一个命名参数reverse=True
,用于反向排序。
2.在python里函数也可以作为返回值。可以在一个函数内部继续定义函数,并返回这个函数,返回这个函数时,这个函数并没有被执行,当调用外部函数时,才会被执行。 例如def lazy_sum(*args):
下再定义个def sum():
,在这个sum函数下实现累加代码,最后整体返回sum函数。那么,当调用时f=lazy_sum([1,2,3,4])
,f接收到的实际上是一个函数,及sum函数,当调用f即f()
时,才会真正计算求和的结果。
在以上例子中,内部sum函数可以引用外部函数的局部变量以及传入的参数,当sum函数被返回时,相关参数和变量都保存在被返回的函数里,这种结构被称为“闭包”。
3.闭包。要牢记一个准则:返回函数不要引用任何循环变量,或者后续会发生变化的变量。例如:
def count():
def f(j):
def g():
return j*j
return g
fs = []
for i in range(1, 4):
fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
return fs
f1,f2,f3=count()
调用f1() , f2() , f3()
才能得到正确结果1,4,9。
以上要注意的就是,fs.append(f(i))
这里,一定要把变化的量给及时传入进去,不然以后调用的时候就会出错。
4.匿名函数,即lambda表达式,其只能是一个表达式,不用写return,返回值就是该表达式的结果。匿名函数也可以赋给一个变量,例如f=lambda x:x*x
,调用时直接f(5)
就行。
5.装饰器。在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator),即在不改变原函数的情况下,给函数增加功能。 一个完整的decorator的写法如下:
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kw):
print('call %s():' % func.__name__)
return func(*args, **kw)
return wrapper
或者针对带参数的decorator:
import functools
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
装饰器还可参考博文
http://www.cnblogs.com/feixuelove1009/p/5541632.html
6.偏函数(Partial function)。python的偏函数主要用于简化函数操作。使用functions.partial来定义函数,它接收三个参数,分别为 函数对象、*args、**kw。例如,定义一个字符串二进制转换: int2=functions.partial(int,base=2)
,然后就可以调用了int2('1000000`)
结果为64。
以上要注意的是,传入参数时对于属性定义,一定要使用命名关键字参数,如以上的base=2,不能直接传入2,不然它会被归到*args这个可变参数里面去,这样就会出错。
查看原文:http://www.wyblog.cn/2016/11/26/python%e5%87%bd%e6%95%b0%e5%bc%8f%e7%bc%96%e7%a8%8b%e5%a4%87%e5%bf%98/