python渐进-函数进阶篇

11.4 函数的嵌套、闭包以及函数传递

在函数里面是可以嵌套函数的,下面的例子就在func1函数里面嵌套了appendl函数。

def func1(): l=[] def appendl(a): l.append(a) appendl(1) appendl(2) print(l)

此时调用函数func1(),可以看到appendl函数在func1里面可以正确执行。

这样的嵌套函数无法在函数外面被调用,appendl只存在于func1的命名空间中。如果想要在函数外面调用嵌套函数,可以把嵌套函数当作返回值返回,此时就会形成闭包。

下面的例子当中appendl被当作返回值return到函数外。

def func1(): l=[] def appendl(a): l.append(a) print(l) return appendl

此时在函数外面也可以调用到appendl了。演示代码如下:

fappend=func1()fappend(2)fappend(3)

此时的输出的结果为:

[2][2, 3]

一个函数能被传递来传递去,是因为python把它看作是一个用户自定义的类型,是一个对象。只要是对象,就可以传递。所以一个函数名可以赋值给别的变量,实现一个函数的改名。演示代码如下:

def funcname(): print('change function name')aliasfunc=funcnamealiasfunc()

11.5 匿名函数lambda

lambda关键字定义了一个匿名函数。这个匿名函数没有函数名,并且只有一行。

定义一个lambda函数,格式类似于:

lambdain-param:out-return

这里lambda是关键字;in-param是输入参数,可以为空;分号是分隔符;out-return是一条语句同时用于返回。整个定义没有一丝赘肉,简洁到不能够再简洁了。

无名函数即使单独定义了,也无法调用。lambda函数必须把函数的句柄赋值给某个变量才可以调用。

以下就是lambda函数应用的一个例子。这个例子对输入的参数加n:

def incn(n): return lambda x:x+ninc4=incn(4)print(inc4(8))

在这里,lambda函数以一个嵌套函数的方式存在,并且它的函数句柄被返回到函数外。以后就可以通过这个函数句柄调用这个lambda函数。

lambda函数也经常会作为实际参数,参与其他函数的调用。比如说在list的sort函数当中,key关键字参数接收的就是一个函数类型,这个函数需要返回一个序列,以便sort函数根据这个序列排序。此时就可以使用lambda函数快速地产生一个序列。演示代码如下:

glist=[('zhang',98),('lee',88),('yu',90)]glist.sort(key=lambda l:l[1])print(glist)

上述代码中lambda返回一个list中每个元素的第二项,sort函数就根据第二项进行排序。

运行的结果为

[('lee', 88), ('yu', 90),('zhang', 98)]

11.6 修饰函数

在定义函数的时候,如果加入了@修饰符,那么说明这个函数将会被另外一个函数修饰。

修饰函数一般都长如下的样子:

@adef b(): print("in b")

其中a是一个函数,它接受一个函数作为参数,并且返回一个新函数。在上面的代码中,a函数接收b函数作为一个参数,然后返回一个新函数。当调用b的时候,实际上调用的就是经过a返回的那个新函数。此时有:

b=a(b)

a函数的作用很广泛,可以给b函数添加新的语句;检查b函数的输入输出;修改b函数的属性等等。

在具体的实现上,a函数一般都包含了一个闭包函数。这个闭包函数负责修饰b的功能。a函数再把这个闭包函数返回,作为一个替代b的新函数。

a函数的实现可能是如下代码:

def a(f): def newf(): print("in newfunc") f() return newf

上面的例子当中,b函数通过a函数的修饰后,调用b函数的时候实际上调用的是a函数里面的闭包函数newf。newf会先执行自己的打印代码,然后再执行传入函数,比如说b函数的代码。

修饰函数也可以带参数。这个时候,带参数的函数必须返回一个函数,用来修饰定义函数。下面的例子当中,inc函数被修饰之后,不再只+1,而是一次+5了,演示代码如下:

@incn(5)def inc(i): return i+1

上面的例子当中incn(5)这个函数必须返回一个函数,用来修饰inc。incn的代码可能为:

def incn(n): def changef(f): def newinc(i): return i+n return newinc return changef

在这里incn(n)函数返回的changef函数,是用来修饰inc函数的,在changef中需要定义了一个闭包函数newinc用来替代inc函数。

这样以来,incn(n)函数就有了三层的嵌套函数了。

这个结构非常绕。此时调用inc函数的话,实际调用的是:

inc(5)(inc)=changef(inc)=newinc

运行一下代码

print(inc(2))

结果是

7

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180620G1UH1X00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。

扫码关注云+社区

领取腾讯云代金券