020函数:内嵌函数和闭包
一、Global关键字
1、屏蔽Shadowing:试图在函数内部修改全局变量时,python会生成一个同名的局部变量,只修改了python创建的局部变量。
>>> count = 5
>>> def Myfun():
count = 10
print(10)
>>> Myfun()
10
>>> print(count)
5
2、运用global修改全局变量
>>> def Myfun():
global count
count = 10
print(10)
>>> Myfun()
10
>>> print(count)
10
二、内嵌函数(内部函数)
>>> def fun1():
print('fun1()正在被调用...')
def fun2():
print('fun2()正在被调用...')
fun2()
>>> fun1()
fun1()正在被调用...
fun2()正在被调用...
>>> fun2()
Traceback (most recent call last):
File "<pyshell#33>", line 1, in <module>
fun2()
NameError: name 'fun2' is not defined
三、闭包closure
1、闭包:函数式编程的一个重要结构
>>> def funx(x):
def funy(y):
return x * y
return funy
>>> i = funx(8)
>>> i(5)
40
>>> funx(8)(5)
40
如果在一个内部函数里【funy】,为在外部作用域【funx】的变量【x】,这个内部函数【funy】就是一个闭包。
2、注意
(1)闭包是由内部函数演变而来,不能在外部函数的外边对内部函数进行调用
(2)闭包中外部函数的局部变量对内部函数的局部变量的关系==全局变量对局部变量的关系:即小对大只能访问不能修改
>>> def fun1():
x = 5
def fun2():
x *= x
return x
return fun2()
>>> fun1()
Traceback (most recent call last):
File "<pyshell#58>", line 1, in <module>
fun1()
File "<pyshell#57>", line 6, in fun1
return fun2()
File "<pyshell#57>", line 4, in fun2
x *= x
UnboundLocalError: local variable 'x' referenced before assignment
3、内部修改外部函数的局部变量
(1)python2:修改容器类型(列表、元组)
>>> def fun1():
x = [5]
def fun2():
x[0] *= x[0]
return x[0]
return fun2()
>>> fun1()
25
(2)python3:运用nonlocal关键字
>>> def fun1():
x = 5
def fun2():
nonlocal x
x *= x
return x
return fun2()
>>> fun1()
25
==================================================================================
思考题
0.如果希望在函数中修改全局变量的值,应该使用什么关键字?
global关键字
1.在嵌套的函数中,如果希望在内部修改外部函数的局部变量,应该使用什么关键字?
nonlocal关键字
2. Python 的函数可以嵌套,但要注意访问的作用域问题哦,请问以下代码存在什么问题呢?
def outside():
print('I am outside!')
def inside():
print('I am inside!')
inside()
调用了内嵌函数,正确的调用应该是:
def outside():
print('I am outside!')
def inside():
print('I am inside!')
inside()
3. 请问为什么代码 A 没有报错,但代码 B 却报错了?应该如何修改?
代码A
def outside():
var = 5
def inside():
var = 3
print(var)
inside()
outside()
代码B
def outside():
var = 5
def inside():
print(var)
var = 3
inside()
outside()
局部变量‘var’在赋值前被引用,应改为
def outside():
var = 5
def inside():
nonlocal var
print(var)
var = 3
inside()
>>> outside()
5
4. 请问如何访问 funIn() 呢?
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn()
funOut()
5. 请问如何访问 funIn() 呢?
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn
funOut()()
6. 以下是“闭包”的一个例子,请你目测下会打印什么内容?
def funX():
x = 5
def funY():
nonlocal x
x += 1
return x
return funY
a = funX()
print(a())
print(a())
print(a())
6
7
8
操作题
0. 请用已学过的知识编写程序,统计下边这个长字符串中各个字符出现的次数并找到小甲鱼送给大家的一句话。
(由于我们还没有学习到文件读取方法,大家下载后拷贝过去即可)
请下载字符串文件:string1.zip
temp = ‘’’粘贴的字符’’’
list = []
for each in temp:
number = temp.count(each)
if each not in list:
if each == '\n':
print('\\n',number)
else:
print(each,number)
list.append(each)
Good luck!
1. 请用已学过的知识编写程序,找出小甲鱼藏在下边这个长字符串中的密码,密码的埋藏点符合以下规律:
a) 每位密码为单个小写字母
b) 每位密码的左右两边均有且只有三个大写字母
(由于我们还没有学习到文件读取方法,大家下载后拷贝过去即可)
请下载字符串文件:string2.zip
Temp = ‘’’粘贴的文本’’’
sum1 = sum2 = sum3 = 0
length = len(temp)
for i in range(length):
if temp[i] == '\n':
continue
if temp[i].isupper():
if sum2 == 0:#小写前的大写
sum1 += 1
else:#小写后的大写
sum3 += 1
continue
if temp[i].islower() and sum1 == 3:#小写,前有3个大写
sum1 = 0
sum2 = 1
goal = i
continue
if temp[i].islower() and sum3 == 3:#小写,前有3个大写
print(temp[goal],end = '')
sum1 = sum2 = sum3 = 0