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
领取专属 10元无门槛券
私享最新 技术干货