1、闭包函数的概念
闭包函数的语法格式如下:
def 外部函数名(外参数):
函数体(包含外局部变量)
def 内部函数名(内参数):
函数体(引用外局部变量或外参数)
return 内部函数名
由此可知,闭包函数是函数嵌套中内函数可引用外函数的局部变量或参数的函数。在闭包函数中,外部函数的返回值是内部函数名。
假设有一个登录界面,需要记录登录次数。要实现登录功能,首先定义login()函数,这个函数有两个参数,第一个参数是用户名,第二个参数是密码。接着对用户名和密码进行判断,如果用户名和密码均正确,那么登录成功,否则登录失败。在登录功能的基础上记录登录次数,则需要在login()函数中定义一个变量,用于记录登录次数,每次判断成功后登录次数加1。这样做是得不到正确的登录次数的,这是因为此时登录次数是函数内的局部变量,随着函数执行完毕后释放内存,这样没有办法一直使用这个局部变量。
要解决这个问题,可以使用闭包函数,代码如下:
- >>> def login(name, pwd):
- ... i = 0
- ... def fun():
- ... if name == 'admin' and pwd == '123456':
- ... nonlocal i
- ... i += 1
- ... print('欢迎登录,这是您第%d次登录' % i)
- ... else:
- ... print('登录失败!')
- ... return fun
- ...
- >>> f = login('admin', '123456')
- >>> f()
- 欢迎登录,这是您第1次登录
- >>> f()
- 欢迎登录,这是您第2次登录
在外部函数login()中已经定义了变量i,而在内部函数fun()中需要修改变量i的值,则需要在内部函数fun()中使用关键字nolocal修饰变量i。
2、闭包函数的案例
下面介绍一个闭包函数的案例。使用闭包函数实现Bob与Will聊天功能,打印聊天记录以及谈话人说的是第几句话。为了实现上述功能,设计一下编程思路:首先创建一个闭包函数person(),然后调用两次闭包函数,实现打印目的。需要注意的是,记录说话次数的变量需要使用关键字nonlocal修饰。代码如下:
- def person(name):
- n = 0
- def do(something):
- nonlocal n
- n += 1
- print('{} say:{} {}的第{}句话'.format(name, something, name, n))
- return do
- Bob = person('Bob')
- Will = person('Will')
- Bob('I am Bob!')
- Will('I am Will!')
- Bob('早上好,Will!')
- Will('早上好,Bob!')
建议将这个程序使用脚本模式运行,运行结果:
- Bob say:I am Bob! Bob的第1句话
- Will say:I am Will! Will的第1句话
- Bob say:早上好,Will! Bob的第2句话
- Will say:早上好,Bob! Will的第2句话
上述程序中,首先定义一个外部函数person(),参数为name,用于接收名字。然后定义一个内部函数do(),参数为something,用于接收聊天内容。内部函数do()结束后,外部函数person()的return返回值是内部函数名do。在do()函数中,使用format()方法打印输出谁说了什么内容。在这个程序中,关键是要记录这是谈话人说的第几句话,需要将变量n初始化设在外部函数中,并在内部函数中使用关键字nonlocal修饰变量n。实现了闭包函数后,定义2个闭包,分别传入参数Bob和Will,并将返回值分别保存在变量Bob和Will中。由于外部函数的返回值是内部函数名do,因此,Bob('I am Bob!')等价于调用内部函数do('I am Bob!')。do()函数中,变量n先增加1,记录是第几句话,然后是一个打印语句,使用format()方法格式化打印字符串。下面3行代码的功能也与这行代码相同。
如果对Python开发感兴趣或者想要深入学习的现在可以免费领取学习大礼包哦(点击领取80G课程资料 备注:领资料)。