学Python的012天
原创:XIAO油菜花
学习进度记录:
《零基础入门学习Python》P21:函数:内嵌函数和闭包
《Python开发入门与爬虫项目实战》:Python中的函数:递归查找
课后思考
0.如果希望在函数中修改全局变量的值,应该使用什么关键字?
1.在嵌套的函数中,如果希望在内部函数修改外部函数的局部变量,应该使用什么关键字?
2.Python 的函数可以嵌套,但要注意访问的作用域问题哦,请问以下代码存在什么问题呢?
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()
4.请问如何访问 funIn() 呢?
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn()
5.请问如何访问 funIn() 呢?
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn
6.以下是“闭包”的一个例子,请你目测下会打印什么内容?
def funX():
x = 5
def funY():
nonlocal x
x += 1
return x
return funY
a = funX()
print(a())
print(a())
print(a())
答案
0.使用global关键字。
1.应使用nonlocal关键字。
2.使用嵌套函数要注意的一点就是作用域问题,inside() 函数是内嵌在outside() 函数中的,所以在外边或者别的函数体里是无法对其进行调用的。正确的调用应该是:
def outside():
print('I am outside!')
def inside():
print('I am inside!')
inside()
outside()
3.看报错的内容是:UnboundLocalError: local variable 'var' referenced before assignment,说的是变量 var 没有被定义就拿来使用。这里 outside() 函数里有一个 var 变量,但要注意的是,内嵌函数 inside() 也有一个同名的变量,Python 为了保护变量的作用域,故将 outside() 的 var 变量屏蔽起来,因此此时是无法访问到外层的 var 变量的。应该修改为:(这题没理解透,感觉参考答案描述的怪怪的)
def outside():
var = 5
def inside():
nonlocal var
print(var)
var = 8
inside()
outside()
4.只需要直接调用 funOut() 即可
5.区别于上一题,这里你就需要用 funOut()() 访问啦
6.会打印:
6
7
8
这……怎么跟全局变量一样了?局部变量 x 不是应该在每次调用的时候都重新初始化了吗?!其实仔细看看就明白了,当 a = funX() 的时候,只要 a 变量没有被重新赋值,funX() 就没有被释放,也就是说局部变量 x 就没有被重新初始化。所以当全局变量不适用的时候,可以考虑使用闭包更稳定和安全。
实战
0.请用已学过的知识编写程序,找出藏在这个长字符串中的密码,密码的埋藏点符合以下规律:a) 每位密码为单个小写字母 b) 每位密码的左右两边均有且只有三个大写字母
string = '''网页中提供的字符串'''
countA = 0 # 统计前边的大写字母
countB = 0 # 统计小写字母
countC = 0 # 统计后边的大写字母
length = len(string)
for i in range(length):
if string[i] == '\n':
continue
"""
|如果string[i]是大写字母:
|-- 如果已经出现小写字母:
|-- -- 统计后边的大写字母
|-- 如果未出现小写字母:
|-- -- 清空后边大写字母的统计
|-- -- 统计前边的大写字母
"""
if string[i].isupper():
if countB:
countC += 1
else:
countC = 0
countA += 1
"""
|如果string[i]是小写字母:
|-- 如果小写字母前边不是三个大写字母(不符合条件):
|-- -- 清空所有记录,重新统计
|-- 如果小写字母前边是三个大写字母(符合条件):
|-- -- 如果已经存在小写字母:
|-- -- -- 清空所有记录,重新统计(出现两个小写字母)
|-- -- 如果该小写字母是唯一的:
|-- -- -- countB记录出现小写字母,准备开始统计countC
"""
if string[i].islower():
if countA != 3:
countA = 0
countB = 0
countC = 0
else:
if countB:
countA = 0
countB = 0
countC = 0
else:
countB = 1
countC = 0
target = i
"""
|如果前边和后边都是三个大写字母:
|-- 如果后边第四个字母也是大写字母(不符合条件):
|-- -- 清空记录B和C,重新统计
|-- 如果后边仅有三个大写字母(符合所有条件):
|-- -- 打印结果,并清空所有记录,进入下一轮统计
"""
if countA == 3 and countC == 3:
if i+1 != length and string[i+1].isupper():
countB = 0
countC = 0
else:
print(string[target], end='')
countA = 3
countB = 0
countC = 0
如果你关注了我,希望你监督我,鼓励我,与我一起学习,一起成长!❤