[Python学习日记-33] Python 中的嵌套函数、匿名函数和高阶函数
简介
嵌套函数
匿名函数
高阶函数
简介
在 Python 当中函数除了能减少重复代码、扩展性强和易维护外,其实还有挺多不通的玩法的,例如嵌套函数、匿名函数、高阶函数等,它们是一些强大的编程概念,可以使代码更加简洁、灵活和高效,下面我们将会一一介绍。
嵌套函数
函数里不仅可以写代码,还可以嵌套函数。而嵌套函数是指在一个函数内部定义另一个函数的情况。嵌套函数可以访问其外部函数的变量,但外部函数无法访问嵌套函数的变量。嵌套函数可以作为内部函数返回或作为参数传递给其他函数使用。代码如下
name = "Python日记"def change():name = "Python日记,成长每一天"def change2():# global name 如果声明了这句,下面的name改的是最外层的全局变层name = "Python日记,成长每一天,天天长高高" # 这句注释掉的话,下面name打印的是哪个值?print("第3层打印", name)change2() # 调用内层函数print("第2层打印", name)change()
print("最外层打印", name)
代码输出如下:
通过上面的例子,我们理解了,每个函数里的变量是互相独立的,变量的查找顺序也是从当前层依次往上层找。在这里可能有的同学会有疑问,这个嵌套函数感觉有点多此一举呀,为什么非要在函数里面再嵌套一个呢?嵌套函数有其自身的有点
- 封装性:内部函数可以访问外部函数的变量,提供了一种封装数据和逻辑的方式,减少了全局变量的使用,提高了代码的安全性和可维护性。
- 增加代码的可读性和组织性:可以将相关的功能分组在一起。
但是最主要的还是因为在后面的一些高级技巧里面我们会使用到这个嵌套函数,例如装饰器,所以我们在这里要先提前了解它的用法。
匿名函数
匿名函数就是不需要显式的指定函数名的函数,也称为lambda函数。匿名函数通常用于简单的功能,可以在需要函数的地方直接定义和使用,而不需要显式地定义一个函数。我们先看一段普通代码
def calc(x,y):return x**y
print(calc(2,5))
换成匿名函数我们应该怎么写呢?
calc = lambda x,y:x**y
print(calc(2,5))
代码输出如下:
你也许会说,用上这个东西没感觉有什么方便呀。确实如果是这么用,确实没什么改进,不过匿名函数主要是和其它函数搭配使用的呢,我们先看一下匿名函数最简单的一个用法,为了方便理解,我们先看用普通的方法如何实现,代码如下
def calc(x):return x**2c = map(calc, [1,5,7,4,8])print(c)
for i in c:print(i)
代码输出如下:
使用匿名函数实现上面代码的功能
c = map(lambda x:x**2, [1,5,7,4,8])print(c) # 返回的是一个内存地址,可以for循环取出来
for i in c:print(i)
代码输出如下:
从输出结果来看,可以看得出实现的结果是完全一样的,并且还少了好几行代码。下面我们来看看匿名函数最复杂的一种用法,即匿名函数内使用三元运算,代码如下
c = map(lambda x:x**2 if x > 10 else x**3, [1,5,7,4,8,12]) # lambda最复杂就是写三元运算
print(c) # 返回的是一个内存地址,可以for循环取出来
for i in c:print(i)
代码输出如下:
从上面的演示来看匿名函数除了减少了几行代码外也没有多大用处,其最复杂的程度只到三元运算,不过由于他的结构简单其特别适合作为高阶函数的参数,比如在 map()、filter() 和 sortef() 等函数中使用。不过它其主要是用作于后面将会讲到的装饰器上。
高阶函数
变量(字符串、整形、浮点型、列表、字典、集合、元组)可以指向函数,函数的参数能接收变量,那么一个函数即可以接收一个或多个函数作为参数,也可以返回一个函数,这种函数就称之为高阶函数。例如,map()、filter() 和 reduce() 是 Python 内置的高阶函数。代码如下
# 取绝对值函数
def get_abs(n):if n < 0:n = int(str(n).strip("-"))return n# 高级函数
def add(x,y,f):return f(x) + f(y)print(add(5,-10,get_abs)) # 函数 get_abs 作为参数传入
代码输出如下:
其实高阶函数只要满足以下任意一个条件,即是高阶函数
- 接收一个或者多个函数作为输入
- 把另一个函数作为返回值
在本篇提到的嵌套函数、匿名函数和高阶函数,在现在所学到的知识看来是毫无用处的,其实这三个函数类型主要的用处是用在后面将会讲到的装饰器上面。