?? 博客主頁:??@披星戴月的賈維斯
?? 歡迎關(guān)注:??點(diǎn)贊??收藏??留言
??系列專欄:?? Python專欄
??請(qǐng)不要相信勝利就像山坡上的蒲公英一樣唾手可得,但是請(qǐng)相信,世界上總有一些美好值得我們?nèi)σ愿?,哪怕粉身碎骨??
??一起加油,去追尋、去成為更好的自己!
提示:以下是本篇文章正文內(nèi)容,下面案例可供參考
前言
????由于最近準(zhǔn)備藍(lán)橋杯,Python專欄也暫停更新了一段時(shí)間,之前也有小伙伴在催我更新,也是感謝小伙伴們的支持了,今天讓我們一起來學(xué)習(xí)Python的函數(shù)、變量作用域、函數(shù)的鏈?zhǔn)秸{(diào)用和遞歸調(diào)用!
??1、函數(shù)
??1.1函數(shù)的定義?
????編程中的函數(shù), 是一段可以重復(fù)使用的代碼,用來獨(dú)立的完成某個(gè)功能,它可以根據(jù)用戶傳遞的數(shù)據(jù)實(shí)現(xiàn)相應(yīng)的功能。
??1.2python中的求數(shù)列,不用函數(shù)
# 求50 - 500的和
ans_n = 0
for i in range(50, 501):
ans_n += i
print(ans_n) # 調(diào)用函數(shù)部分
# 求520 - 1314 的和
the_ans = 0;
for i in range(520, 1315):
the_ans += i
print(the_ans)
可以發(fā)現(xiàn), 這幾組代碼基本是相似的, 只有一點(diǎn)點(diǎn)差異. 可以把重復(fù)代碼提取出來, 做成一個(gè)函數(shù)
??1.3python求數(shù)列的和, 使用函數(shù)
# 定義一個(gè)求和函數(shù)
def count_sum(begin, end):
ans = 0
for i in range(begin, end+1):
ans += i
print(ans)
#調(diào)用函數(shù)
# 求50, 500的和
count_sum(50, 500)
# 求520 - 1314 的和
count_sum(520, 1314)
可以明顯看到, 重復(fù)的代碼已經(jīng)被消除了。
??2、函數(shù)的語法格式和參數(shù)
??創(chuàng)建函數(shù)/定義函數(shù)
def 函數(shù)名(形參列表):
函數(shù)體
return 返回值
??調(diào)用函數(shù)/使用函數(shù)
函數(shù)名(實(shí)參列表) // 不考慮返回值
返回值 = 函數(shù)名(實(shí)參列表) // 考慮返回值
??我們都知道函數(shù)定義并不會(huì)執(zhí)行函數(shù)體內(nèi)容, 必須要調(diào)用才會(huì)執(zhí)行. 調(diào)用幾次就會(huì)執(zhí)行幾次。
def test1():
print('hello')
# 如果光是定義函數(shù), 而不調(diào)用, 則不會(huì)執(zhí)行.
??函數(shù)必須先定義, 再使用
#調(diào)用函數(shù)
# 求50, 500的和
count_sum(50, 500)
# 求520 - 1314 的和
count_sum(520, 1314)
#調(diào)用函數(shù)
def count_sum(begin, end):
ans = 0
for i in range(begin, end+1):
ans += i
print(ans)
??函數(shù)參數(shù)
在函數(shù)定義的時(shí)候, 可以在 ( ) 中指定 “形式參數(shù)” (簡稱 形參), 然后在調(diào)用的時(shí)候, 由調(diào)用者把 “實(shí)際參數(shù)” (簡稱 實(shí)參) 傳遞進(jìn)去.
這樣就可以做到一份函數(shù), 針對(duì)不同的數(shù)據(jù)進(jìn)行計(jì)算處理。
我們用之前的代碼來分析:
def Sum(begin, end):
thesum = 0
for i in range(begin, end+1):
thesum += i
print(thesum)
# 求1 - 100的和
Sum(1, 100)
在上面代碼中,begin, end 就是函數(shù)的參數(shù), 1, 101, 就是函數(shù)的實(shí)參。
注意:
- 一個(gè)函數(shù)可以有一個(gè)形參, 也可以有多個(gè)形參, 也可以沒有形參.
- 一個(gè)函數(shù)的形參有幾個(gè), 那么傳遞實(shí)參的時(shí)候也得傳幾個(gè). 保證個(gè)數(shù)要匹配.
- 和 C++ / Java 不同, Python 是動(dòng)態(tài)類型的編程語言, 函數(shù)的形參不必指定參數(shù)類型. 換句話說, 一個(gè)函數(shù)可以支持多種不同類型的參數(shù)
def test(a, b, c):
print(a, b, c)
test(2000)
def fun(n):
print(n)
fun(666)
fun('good')
fun('hello word')
程序輸出
666
good
hello word
??3、函數(shù)返回值
函數(shù)的參數(shù)可以視為是函數(shù)的 “輸入”, 則函數(shù)的返回值, 就可以視為是函數(shù)的 “輸出” .
此處的 “輸入”, “輸出” 是更廣義的輸入輸出, 不是單純指通過控制臺(tái)輸入輸出.
我們可以把函數(shù)想象成一個(gè) “工廠”. 工廠需要買入原材料, 進(jìn)行加工, 并生產(chǎn)出產(chǎn)品.
函數(shù)的參數(shù)就是原材料, 函數(shù)的返回值就是生產(chǎn)出的產(chǎn)品.
我們之前寫的求一段區(qū)間和的函數(shù)代碼可以轉(zhuǎn)換成
def Sum(begin, end):
sum = 0
for i in range(beg, end + 1):
sum += i
return sum
result = Sum(1, 100)
print(result)
這兩個(gè)代碼的區(qū)別就在于, 前者直接在函數(shù)內(nèi)部進(jìn)行了打印, 后者則使用 return 語句把結(jié)果返回給函數(shù)調(diào)用者, 再由調(diào)用者負(fù)責(zé)打印。
我們一般傾向于第二種寫法,就是有返回值的寫法。
實(shí)際開發(fā)中我們的一個(gè)通常的編程原則, 是 “邏輯和用戶交互分離”. 而第一種寫法的函數(shù)中, 既包含了計(jì)算邏輯, 又包含了和用戶交互(打印到控制臺(tái)上). 這種寫法是不太好的, 如果后續(xù)我們需要的是把計(jì)算結(jié)果保存到文件中, 或者通過網(wǎng)絡(luò)發(fā)送, 或者展示到圖形化界面里, 那么第一種寫法的函數(shù), 就難以勝任了.
而第二種寫法則專注于做計(jì)算邏輯, 不負(fù)責(zé)和用戶交互. 那么就很容易把這個(gè)邏輯搭配不同的用戶交互代碼, 來實(shí)現(xiàn)不同的效果.
- 一個(gè)函數(shù)中可以有多個(gè) return 語句, 比如if語句里,如果括號(hào)內(nèi)的條件是對(duì)的就返回一種,else返回另一個(gè)值
- 執(zhí)行到 return 語句, 函數(shù)就會(huì)立即執(zhí)行結(jié)束, 回到調(diào)用位置。
- 一個(gè)函數(shù)是可以一次返回多個(gè)返回值的. 是用來分割多個(gè)返回值
def getPoint():
x = 10
y = 20
return x, y
a, b = getPoint()
- 如果只想關(guān)注其中的部分返回值, 可以使用 _ 來忽略不想要的返回值.
def getPoint():
x = 10
y = 20
return x, y
_, b = getPoint()
??4、變量作用域
分析一下代碼:
def getPoint():
x = 10
y = 20
return x, y
x, y = getPoint()
在這個(gè)代碼中, 函數(shù)內(nèi)部存在 x, y, 函數(shù)外部也有 x, y.
但是這兩組 x, y 不是相同的變量, 而只是恰好有一樣的名字.
??變量只能在所在的函數(shù)內(nèi)部生效.
在函數(shù) get_point() 內(nèi)部定義的 x, y 只是在函數(shù)內(nèi)部生效. 一旦出了函數(shù)的范圍, 這兩個(gè)變量就不再生效了.
def get_point():
x = 10
y = 20
return x, y
get_point()
print(x, y)
在不同的作用域中, 允許存在同名的變量。
雖然名字相同, 實(shí)際上是不同的變量。
x = 20
def test():
x = 10
print(f'函數(shù)內(nèi)部 x = {x}')
test()
print(f'函數(shù)外部 x = {x}')
注意:
- 在函數(shù)內(nèi)部的變量, 也稱為 “局部變量”
- 不在任何函數(shù)內(nèi)部的變量, 也稱為 “全局變量”
如果函數(shù)內(nèi)部嘗試訪問的變量在局部不存在, 就會(huì)嘗試去全局作用域中查找。
如果是想在函數(shù)內(nèi)部, 修改全局變量的值, 需要使用 global 關(guān)鍵字聲明
x = 60
def Test1():
global x
x = 10
print(f'函數(shù)內(nèi)部 x = {x}')
Test1()
print(f'函數(shù)外部 x = {x}')
如果此處沒有 global , 則函數(shù)內(nèi)部的 x = 10 就會(huì)被視為是創(chuàng)建一個(gè)局部變量 x, 這樣就和全局變量 x 不相關(guān)了.
if / while / for 等語句塊不會(huì)影響到變量作用域
換而言之, 在 if / while / for 中定義的變量, 在語句外面也可以正常使用.
for i in range(1, 10):
print(f'函數(shù)內(nèi)部 i = {i}')
print(f'函數(shù)外部 i = {i}')
輸出
函數(shù)內(nèi)部 i = 1
函數(shù)內(nèi)部 i = 2
函數(shù)內(nèi)部 i = 3
函數(shù)內(nèi)部 i = 4
函數(shù)內(nèi)部 i = 5
函數(shù)內(nèi)部 i = 6
函數(shù)內(nèi)部 i = 7
函數(shù)內(nèi)部 i = 8
函數(shù)內(nèi)部 i = 9
函數(shù)外部 i = 9
??函數(shù)執(zhí)行過程
- 調(diào)用函數(shù)才會(huì)執(zhí)行函數(shù)體代碼. 不調(diào)用則不會(huì)執(zhí)行.
- 函數(shù)體執(zhí)行結(jié)束(或者遇到 return 語句), 則回到函數(shù)調(diào)用位置, 繼續(xù)往下執(zhí)行.
5、??函數(shù)的鏈?zhǔn)秸{(diào)用和遞歸調(diào)用
??鏈?zhǔn)秸{(diào)用
把一個(gè)函數(shù)的返回值, 作為另一個(gè)函數(shù)的參數(shù), 這種操作稱為 鏈?zhǔn)秸{(diào)用。
# 判定是否是偶數(shù)
def fun(num):
if num % 2 != 0:
return False
else:
return True
ans = isOdd(2000)
print(ans)
實(shí)際上也可以簡化寫作
print(fun(2000))
??嵌套調(diào)用
函數(shù)內(nèi)部還可以調(diào)用其他的函數(shù), 這個(gè)動(dòng)作稱為 “嵌套調(diào)用”
def test():
print("執(zhí)行函數(shù)內(nèi)部代碼")
print("執(zhí)行函數(shù)內(nèi)部代碼")
print("執(zhí)行函數(shù)內(nèi)部代碼")
test 函數(shù)內(nèi)部調(diào)用了 print 函數(shù), 這里就屬于嵌套調(diào)用.
注意:一個(gè)函數(shù)里面可以嵌套調(diào)用任意多個(gè)函數(shù)。
函數(shù)嵌套的過程是非常靈活的.
代碼示例:
def k1():
print("函數(shù) k1")
def k2():
print("函數(shù) k2")
a()
def k3():
print("函數(shù) k3")
b()
def k4():
print("函數(shù) k4")
c()
d()
程序輸出:
函數(shù) k4
函數(shù) k3
函數(shù) k2
函數(shù) k1
在Python中,使用特定的數(shù)據(jù)結(jié)構(gòu)來表示函數(shù)之間的調(diào)用關(guān)系,稱為函數(shù)調(diào)用堆棧每個(gè)函數(shù)調(diào)用,
將在調(diào)用堆棧中添加一個(gè)元素,稱為堆棧幀
您可以通過PyCharm調(diào)試器查看函數(shù)調(diào)用堆棧和堆??蚣?br> 在調(diào)試狀態(tài)下,函數(shù)調(diào)用堆棧通常顯示在PyCharm的左下角.
??函數(shù)遞歸
在我之前的文章中,不止一次提到過遞歸的問題,比如dfs算法,經(jīng)典的斐波那契問題等等,所以遞歸即是嵌套調(diào)用 中的一種特殊情況, 即一個(gè)函數(shù)嵌套調(diào)用自己。
代碼示例: 遞歸計(jì)算 10!
def fun(n):
if n == 1:
return 1
return n * fun(n - 1)
asn_n = fun(10)
print(asn_n)
程序輸出:
3628800
如上代碼就是典型的遞歸操作. 在 fun函數(shù)內(nèi)部, 又調(diào)用了 fun自身.
注意:
- 存在遞歸結(jié)束條件. 比如 if n == 1 就是結(jié)束條件. 當(dāng) n 為 1 的時(shí)候, 遞歸就結(jié)束了.
- 每次遞歸的時(shí)候, 要保證函數(shù)的實(shí)參是逐漸逼近結(jié)束條件的
如果不能滿足上述條件,將發(fā)生“無限遞歸”這是一個(gè)典型的代碼錯(cuò)誤。
遞歸的優(yōu)點(diǎn)
- 遞歸類似于 “數(shù)學(xué)歸納法” , 明確初始條件, 和遞推公式, 就可以解決一系列的問題.。
- 遞歸代碼往往代碼通常來說比較短。
遞歸的缺點(diǎn)文章來源:http://www.zghlxwxcb.cn/news/detail-413134.html
- 遞歸代碼往往難以理解, 很容易超出掌控范圍
- 遞歸代碼容易出現(xiàn)棧溢出的情況,遞歸是在棧上遞歸的,而且棧上的空間會(huì)比較小。
- 遞歸代碼往往可以轉(zhuǎn)換成等價(jià)的循環(huán)代碼. 并且通常來說循環(huán)版本的代碼執(zhí)行效率要略高于遞歸版
本
總結(jié)
????文介紹了Python的函數(shù)、變量作用域、函數(shù)的鏈?zhǔn)秸{(diào)用和遞歸調(diào)用。函數(shù)是可重用的代碼塊,可以在程序中多次調(diào)用。變量作用域定義了變量的可見性和訪問范圍。鏈?zhǔn)秸{(diào)用使代碼更簡潔、易讀。遞歸調(diào)用是一種函數(shù)調(diào)用自身的技術(shù),可以解決某些問題,希望大家讀后能夠有所收獲!文章來源地址http://www.zghlxwxcb.cn/news/detail-413134.html
到了這里,關(guān)于【30天python從零到一】---第六天:函數(shù)、變量作用域、函數(shù)的鏈?zhǔn)秸{(diào)用和遞歸調(diào)用的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!