原創(chuàng):XIAO油菜花
學(xué)習(xí)進(jìn)度記錄:
《零基礎(chǔ)入門學(xué)習(xí)Python》P21:函數(shù):內(nèi)嵌函數(shù)和閉包
《Python開發(fā)入門與爬蟲項目實戰(zhàn)》:Python中的函數(shù):遞歸查找
課后思考
0.如果希望在函數(shù)中修改全局變量的值沫屡,應(yīng)該使用什么關(guān)鍵字?
1.在嵌套的函數(shù)中冈欢,如果希望在內(nèi)部函數(shù)修改外部函數(shù)的局部變量,應(yīng)該使用什么關(guān)鍵字?
2.Python 的函數(shù)可以嵌套败去,但要注意訪問的作用域問題哦暴构,請問以下代碼存在什么問題呢泛释?
def outside():
print('I am outside!')
def inside():
print('I am inside!')
inside()
3.請問為什么代碼 A 沒有報錯础米,但代碼 B 卻報錯了袱蜡?應(yīng)該如何修改德挣?
#代碼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.以下是“閉包”的一個例子,請你目測下會打印什么內(nèi)容俊啼?
def funX():
x = 5
def funY():
nonlocal x
x += 1
return x
return funY
a = funX()
print(a())
print(a())
print(a())
答案
0.使用global關(guān)鍵字肺缕。
1.應(yīng)使用nonlocal關(guān)鍵字。
2.使用嵌套函數(shù)要注意的一點就是作用域問題授帕,inside() 函數(shù)是內(nèi)嵌在outside() 函數(shù)中的同木,所以在外邊或者別的函數(shù)體里是無法對其進(jìn)行調(diào)用的。正確的調(diào)用應(yīng)該是:
def outside():
print('I am outside!')
def inside():
print('I am inside!')
inside()
outside()
3.看報錯的內(nèi)容是:UnboundLocalError: local variable 'var' referenced before assignment跛十,說的是變量 var 沒有被定義就拿來使用彤路。這里 outside() 函數(shù)里有一個 var 變量,但要注意的是芥映,內(nèi)嵌函數(shù) inside() 也有一個同名的變量洲尊,Python 為了保護(hù)變量的作用域,故將 outside() 的 var 變量屏蔽起來奈偏,因此此時是無法訪問到外層的 var 變量的坞嘀。應(yīng)該修改為:(這題沒理解透,感覺參考答案描述的怪怪的)
def outside():
var = 5
def inside():
nonlocal var
print(var)
var = 8
inside()
outside()
4.只需要直接調(diào)用 funOut() 即可
5.區(qū)別于上一題惊来,這里你就需要用 funOut()() 訪問啦
6.會打永錾:
6
7
8
這……怎么跟全局變量一樣了?局部變量 x 不是應(yīng)該在每次調(diào)用的時候都重新初始化了嗎裁蚁?矢渊!其實仔細(xì)看看就明白了,當(dāng) a = funX() 的時候枉证,只要 a 變量沒有被重新賦值矮男,funX() 就沒有被釋放,也就是說局部變量 x 就沒有被重新初始化室谚。所以當(dāng)全局變量不適用的時候毡鉴,可以考慮使用閉包更穩(wěn)定和安全崔泵。
實戰(zhàn)
0.請用已學(xué)過的知識編寫程序,找出藏在這個長字符串中的密碼猪瞬,密碼的埋藏點符合以下規(guī)律:a) 每位密碼為單個小寫字母 b) 每位密碼的左右兩邊均有且只有三個大寫字母
string = '''網(wǎng)頁中提供的字符串'''
countA = 0 # 統(tǒng)計前邊的大寫字母
countB = 0 # 統(tǒng)計小寫字母
countC = 0 # 統(tǒng)計后邊的大寫字母
length = len(string)
for i in range(length):
if string[i] == '\n':
continue
"""
|如果string[i]是大寫字母:
|-- 如果已經(jīng)出現(xiàn)小寫字母:
|-- -- 統(tǒng)計后邊的大寫字母
|-- 如果未出現(xiàn)小寫字母:
|-- -- 清空后邊大寫字母的統(tǒng)計
|-- -- 統(tǒng)計前邊的大寫字母
"""
if string[i].isupper():
if countB:
countC += 1
else:
countC = 0
countA += 1
"""
|如果string[i]是小寫字母:
|-- 如果小寫字母前邊不是三個大寫字母(不符合條件):
|-- -- 清空所有記錄管削,重新統(tǒng)計
|-- 如果小寫字母前邊是三個大寫字母(符合條件):
|-- -- 如果已經(jīng)存在小寫字母:
|-- -- -- 清空所有記錄,重新統(tǒng)計(出現(xiàn)兩個小寫字母)
|-- -- 如果該小寫字母是唯一的:
|-- -- -- countB記錄出現(xiàn)小寫字母撑螺,準(zhǔn)備開始統(tǒng)計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含思,重新統(tǒng)計
|-- 如果后邊僅有三個大寫字母(符合所有條件):
|-- -- 打印結(jié)果,并清空所有記錄甘晤,進(jìn)入下一輪統(tǒng)計
"""
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
如果你關(guān)注了我含潘,希望你監(jiān)督我,鼓勵我线婚,與我一起學(xué)習(xí)遏弱,一起成長!?