笔记
global关键字

格式:global 变量名 ;使该变量变为全局变量。
内嵌函数
在一个函数(外部函数)内部嵌套定义另一个函数。
内部函数的整个作用域全都且只在外部函数内,即只能在外部函数内调用内部函数,不可以在外部函数外调用内部函数。
外部函数与内部函数两者局部变量之间的关系,就如同之前所讨论的全局变量与局部变量之间的关系。
如上图,Fun2()中试图改变外部函数Fun1的局部变量x,此时屏蔽机制使得Python在Fun2的栈中自动创建一个新的局部变量x,新的x没有赋值,从而导致程序报错。
解决方法:
方法一:在老版的Python中,需要通过容器类型的变量进行解决,因为容器类型的变量不是存放于栈中的。如下图:
方法二:使用nonlocal()
注:global是把局部变量转换为全局变量;nonlocal是把内部函数的局部变量转换为外部函数的局部变量。
闭包(closure)
函数式的重要语法结构。
我们可以将闭包理解为一种特殊的函数,这种函数由两个函数的嵌套组成,且称之为外函数和内函数,外函数返回值是内函数的引用,此时就构成了闭包。
参考链接:https://blog.csdn.net/weixin_44141532/article/details/87116038
https://baijiahao.baidu.com/s?id=1601023189180094497&wfr=spider&for=pc
如何对形成闭包的内部函数进行调用?
例如有如下闭包:
方式一(“曲线救国”):
可见FunX(8)返回的是一个函数对象,并赋值给i,使i也变为函数,再对i进行调用,即调用了内部函数。
方式二(直接调用):
内函数的引用
对比如下两例(取自课后作业测试题第5,6题):
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn
def funOut():
def funIn():
print('宾果!你成功访问到我啦!')
return funIn()
前者为闭包,使用上文所述的两种方式均可。
后者则直接调用 funOut()即可。
课后作业
https://fishc.com.cn/forum.php?mod=viewthread&tid=42685&page=1
测试题:
0.答:global关键字。
1.答:nonlocal关键字。
2.答:一方面,在函数outside中没有对inside进行调用,使得inside的定义毫无意义;另一方面,inside属于内部函数,只能在其外部函数outside中进行调用,不能在外部函数外面调用。
3.答:
原因:对于代码B,在inside中,由于局部变量var与其外部函数中的局部变量var重名。根据Python的屏蔽机制,inside中会重新在其栈内创建一个同名的新变量var,而此时var还未赋值就被print调用,自然会报错。而对于代码A,则会正常输出3。
修改:
def outside():
var = 5
def inside():
nonlocal var
print(var)
var = 3
inside()
outside()
4.答:
直接调用funOut()即可:
funOut()
宾果!你成功访问到我啦!
5.答:
方式一:
i = funOut()
i()
方式二:
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
注:a = funX()并不意味着funX()执行完了。只要 a 变量没有被重新赋值,funX() 就没有被释放,也就是说局部变量 x 就没有被重新初始化。所以当全局变量不适用的时候,可以考虑使用闭包更稳定和安全。你还可以参考 -> 游戏中的角色移动:闭包在实际开发中的作用。
动动手:
0.答:
string = '''拷贝过来的字符串'''
list1 = list(string)
char = []
answer = []
for each in string:
if each not in char:
char.append(each)
for each in char:
if each == '\n':
print('\\n字符出现了%d次'%string.count(each))
else:
print('%s字符出现了%d次'%(each,string.count(each)))
for each in char:
if each.isalnum():
answer.append(each*string.count(each))
print(answer)
输出:
%字符出现了6104次
$字符出现了6046次
@字符出现了6157次
_字符出现了6112次
^字符出现了6030次
#字符出现了6115次
)字符出现了6186次
&字符出现了6043次
!字符出现了6079次
+字符出现了6066次
]字符出现了6152次
*字符出现了6034次
}字符出现了6105次
[字符出现了6108次
(字符出现了6154次
{字符出现了6046次
\n字符出现了1219次
G字符出现了1次
O字符出现了2次
D字符出现了1次
L字符出现了1次
U字符出现了1次
C字符出现了1次
K字符出现了1次
['G', 'OO', 'D', 'L', 'U', 'C', 'K']
1.答:
string = '''此处为文本内容'''
def ispassword(char_index):
if char.islower():
j = 0
for i in range(1,4):
if string[char_index + i].isupper() and string[char_index - i].isupper():
j += 1
if char_index > 3 and char_index < (length - 3):
if string[char_index + 4].islower() and string[char_index - 4].islower():
j += 1
if j == 4:
list1.append(char)
elif char_index == 3 and char_index == (length - 3) and j == 3:
list1.append(char)
list1 = []
length = len(string)
char_index = 3 #从第四个字符开始查找
char = string[char_index]
ispassword(char_index) #判断第四个字符是否为密码
for char in string[4:length - 3]: #判断第5——length-4之间的字符是否为密码
char_index += 1
ispassword(char_index)
char = string[length - 3] #判读第length-3个字符是否为密码
ispassword(char_index)
密码存储在list1中:
>>> list1
['i', 'l', 'o', 'v', 'e', 'f', 'i', 's', 'h', 'c']
>>>