15.python函数式编程(二)—返回函数,匿名函数

时间:2021-11-25 22:41:31
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。

有一点注意的地方是,只能有一个表达式。可以将匿名函数赋给一个变量,然后使用。也可以返回匿名函数。

其实我感觉匿名函数这个东西,没什么用。有点华而不实。看起来这个函数的功能是为了防止函数名冲突,或者是一定程度上方便程序员。因为他不用再定义一个函数。但我想,一个有着良好编程习惯的程序员,是不怕这个麻烦的。所以就不多说了。