筆記
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']
>>>