1)返回函数
(1)返回函数地址
高阶函数除了可以接收函数作为输入以外,还可以输出函数。示例代码如下:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- def func(*arg): def sum(): he=0 for n in arg:
he=n+arg
return he return sumprint func([1,2,3,4])print func([1,2,3,4])
输出结果为下:
<function sum at 0x023F3A70> <function sum at 0x023F3A70>
这输出的是什么鬼???手动黑人问号。
然后我们这里改一下:
f1=func([1,2,3,4]) f2=func([1,2,3,4]) print f1 print f2
则输出结果变为:
<function sum at 0x02333A70> <function sum at 0x023339F0>
这是怎么回事??这又是什么鬼!
这里我们求一个可变参数的值。我们先定义了外函数func,设定可变参数*arg为形参。再定义了内函数sum()。这时,内函数保存,或者说是引用了外函数的参数值*arg。然后返回结果he。外函数则保存了该内函数的地址。在我理解看来,定义函数的过程,其实就是为某一段语句(函数体)指定一段内存地址(函数名)存放的过程。这个过程最终完成后,生成了一个内存地址(函数名)。这就解释了程序,为什么会打印一个16进制数,这个数是sum函数的地址。这里再为数据结构鼓掌!(呱唧。。呱唧。。)既然内函数生成了一个地址,那么对于外函数来说,当然是返回该地址了。
对于上面的程序来说,由于内函数每次执行的时候都会为函数名新分配一个内存地址。所以两次返回的地址是不同的。这就解释了,为什么两次返回地址不一样。而第一个程序,只分配了一个地址,所以打印的地址一样。
你可能想问了。那怎么得到结果呢?
地址都有了,只要执行就可以了啦!
f=func(1,2,3,4) print f()
输出:10
在这之前,我犯了一个错误:
he=n+he
我写成了
he=n+arg
结果,报错”TypeError: unsupported operand type(s) for +: 'int' and 'tuple'“,一定要细心啊。
(2)闭包
首先来看一下什么是闭包,当内函数引用了外函数的临时变量,而且返回后,下次函数继续引用内函数的局部变量,这就形成了一个闭包。
这里要注意的是:返回的函数没有立即执行,直到调用了f(),才执行。
另外,在内函数中,不要使用局部循环变量i。我们看一个例子:来源于廖雪峰
#!/usr/bin/env python3 # -*- coding: utf-8 -*- def func(): fs = [] for i in range(1, 4): def f(): return i*i fs.append(f) return fs f1,f2,f3=func() list=[f1,f2,f3] print list
但是很遗憾,我没有成功,输出打印后,是这样的:
[<function f at 0x025B3A70>, <function f at 0x025B39F0>, <function f at 0x025B3AF0>]
从字面上看是我把各个列表元素的地址打印出来了。也就是说我们需要,找到地址所对应的值,因此我试着用*符号来指向值,但是提示:invalid syntax。这个问题先留着,回头再看。
2)匿名函数
什么是匿名函数呢?就是不需要起名字的函数。示例代码如下:
map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
实际上就是:
def f(x): return x * x
lambda是匿名函数的关键字,定义参数x,返回x*x。
有一点注意的地方是,只能有一个表达式。可以将匿名函数赋给一个变量,然后使用。也可以返回匿名函数。
其实我感觉匿名函数这个东西,没什么用。有点华而不实。看起来这个函数的功能是为了防止函数名冲突,或者是一定程度上方便程序员。因为他不用再定义一个函数。但我想,一个有着良好编程习惯的程序员,是不怕这个麻烦的。所以就不多说了。