成武縣住房和城鄉(xiāng)建設(shè)廳網(wǎng)站百度信息流推廣和搜索推廣
各位CSDN的uu們你們好呀,今天小雅蘭的內(nèi)容是Python的函數(shù)呀,下面,就讓我們進(jìn)入函數(shù)的世界吧
首先可以選擇性地看一下小雅蘭很久之前寫的C語言函數(shù)章節(jié)的知識:
函數(shù)——“C”_認(rèn)真學(xué)習(xí)的小雅蘭.的博客-CSDN博客
函數(shù)遞歸+青蛙跳臺階——“C”_認(rèn)真學(xué)習(xí)的小雅蘭.的博客-CSDN博客
函數(shù)是什么
語法格式
函數(shù)參數(shù)
函數(shù)返回值
變量作用域
函數(shù)執(zhí)行過程
函數(shù)是什么
編程中的函數(shù)和數(shù)學(xué)中的函數(shù)有一定的相似之處.
數(shù)學(xué)上的函數(shù), 比如 y = sin x , x 取不同的值, y 就會得到不同的結(jié)果.
編程中的函數(shù), 是一段可以被重復(fù)使用的代碼片段 .
?代碼示例: 求數(shù)列的和, 不使用函數(shù)
# 1. 求 1 - 100 的和
theSum = 0
for i in range(1, 101):theSum += i
print(theSum)
?
# 2. 求 300 - 400 的和
theSum = 0
for i in range(300, 401):theSum += i
print(theSum)
?
# 3. 求 1 - 1000 的和
theSum = 0
for i in range(1, 1001):theSum += i
print(theSum)
可以發(fā)現(xiàn), 這幾組代碼基本是相似的, 只有一點點差異.
可以把重復(fù)代碼提取出來, 做成一個函數(shù)
實際開發(fā)中, 復(fù)制粘貼是一種不太好的策略. 實際開發(fā)的重復(fù)代碼可能存在幾十份甚至上百份.
一旦這個重復(fù)代碼需要被修改, 那就得改幾十次, 非常不便于維護(hù).
?代碼示例: 求數(shù)列的和, 使用函數(shù)
# 定義函數(shù)
def calcSum(beg, end):theSum = 0for i in range(beg, end + 1):theSum += iprint(theSum)
# 調(diào)用函數(shù)
calcSum(1,100)
calcSum(300, 400)
calcSum(1, 1000)
可以明顯看到, 重復(fù)的代碼已經(jīng)被消除了. ?
語法格式
創(chuàng)建函數(shù)/定義函數(shù)
def 函數(shù)名(形參列表):函數(shù)體return 返回值
調(diào)用函數(shù)/使用函數(shù)
函數(shù)名(實參列表) ? ? ? ? ? #不考慮返回值
返回值 = 函數(shù)名(實參列表) ? #考慮返回值
函數(shù)定義并不會執(zhí)行函數(shù)體內(nèi)容, 必須要調(diào)用才會執(zhí)行. 調(diào)用幾次就會執(zhí)行幾次
def test1():print('hello')
# 如果光是定義函數(shù), 而不調(diào)用, 則不會執(zhí)行.
#函數(shù)調(diào)用才會真正執(zhí)行函數(shù)體里面的代碼
#函數(shù)經(jīng)過一次定義之后,可以被調(diào)用多次
def test():print('hello')print('hello')print('hello')
test()
test()
test()
test()
看到這個圖片,發(fā)現(xiàn):第一個test下面畫了波浪線,這是警告的意思
?
??
函數(shù)必須先定義, 再使用. ?
test3() # 還沒有執(zhí)行到定義, 就先執(zhí)行調(diào)用了, 此時就會報錯.
def test3():print('hello')
?
動漫里釋放技能之前, 需要大喊招式的名字, 就是 "先定義, 再使用".
函數(shù)參數(shù)?
在函數(shù)定義的時候, 可以在 ( ) 中指定 "形式參數(shù)" (簡稱 形參), 然后在調(diào)用的時候, 由調(diào)用者把 "實際參數(shù)" (簡稱 實參) 傳遞進(jìn)去.
這樣就可以做到一份函數(shù), 針對不同的數(shù)據(jù)進(jìn)行計算處理.
考慮前面的代碼案例:
def calcSum(beg, end):theSum = 0for i in range(beg, end + 1):theSum += iprint(theSum)
calcSum(1, 100)
calcSum(300, 400)
calcSum(1, 1000)
上面的代碼中, beg, end 就是函數(shù)的形參. 1, 100 / 300, 400 就是函數(shù)的實參.
- 在執(zhí)行 sum(1, 100) 的時候, 就相當(dāng)于 beg = 1, end = 100 , 然后在函數(shù)內(nèi)部就可以針對 1- 100 進(jìn)行運算.
- 在執(zhí)行 sum(300, 400) 的時候, 就相當(dāng)于 beg = 300, end = 400 , 然后在函數(shù)內(nèi)部就可以針對 300-400 進(jìn)行運算.
實參和形參之間的關(guān)系, 就像簽合同一樣.
?甲方, 乙方 這就相當(dāng)于形參. 湯老濕, 蔡徐坤 就是實參.
def 簽合同(甲方, 乙方):合同內(nèi)容....簽合同('湯老濕', '蔡徐坤')
簽合同('湯老濕', '鹿晗')
簽合同('湯老濕', '吳磊')
注意:
- 一個函數(shù)可以有一個形參, 也可以有多個形參, 也可以沒有形參.
- 一個函數(shù)的形參有幾個, 那么傳遞實參的時候也得傳幾個. 保證個數(shù)要匹配.
def test(a, b, c):print(a, b, c)
test(10)
和 C++ / Java 不同, Python 是動態(tài)類型的編程語言, 函數(shù)的形參不必指定參數(shù)類型. 換句話說, 一個 函數(shù)可以支持多種不同類型的參數(shù). ?
def test(a):print(a)
test(10)
test('hello')
test(True)
def add(x,y):return x + y
print(add(10,20))
print(add(1.5,2.5))
print(add('hello ','world'))
?
?
?函數(shù)返回值
函數(shù)的參數(shù)可以視為是函數(shù)的 "輸入", 則函數(shù)的返回值, 就可以視為是函數(shù)的 "輸出" .
此處的 "輸入", "輸出" 是更廣義的輸入輸出, 不是單純指通過控制臺輸入輸出.
我們可以把函數(shù)想象成一個 "工廠". 工廠需要買入原材料, 進(jìn)行加工, 并生產(chǎn)出產(chǎn)品.
函數(shù)的參數(shù)就是原材料, 函數(shù)的返回值就是生產(chǎn)出的產(chǎn)品.
?
?下列代碼
def calcSum(beg, end):theSum = 0for i in range(beg, end + 1):theSum += iprint(theSum)
calcSum(1, 100)
可以轉(zhuǎn)換成
def calcSum(beg, end):theSum = 0for i in range(beg, end + 1):theSum += ireturn theSum
result = calcSum(1, 100)
print(result)
這兩個代碼的區(qū)別就在于, 前者直接在函數(shù)內(nèi)部進(jìn)行了打印, 后者則使用 return 語句把結(jié)果返回給函數(shù) 調(diào)用者, 再由調(diào)用者負(fù)責(zé)打印.
?
我們一般傾向于第二種寫法.
實際開發(fā)中我們的一個通常的編程原則, 是 "邏輯和用戶交互分離". 而第一種寫法的函數(shù)中, 既包含 了計算邏輯, 又包含了和用戶交互(打印到控制臺上). 這種寫法是不太好的, 如果后續(xù)我們需要的是 把計算結(jié)果保存到文件中, 或者通過網(wǎng)絡(luò)發(fā)送, 或者展示到圖形化界面里, 那么第一種寫法的函數(shù),
就難以勝任了.
而第二種寫法則專注于做計算邏輯, 不負(fù)責(zé)和用戶交互. 那么就很容易把這個邏輯搭配不同的用戶 交互代碼, 來實現(xiàn)不同的效果.
?
?
一個函數(shù)中可以有多個 return 語句 ?
?
# 判定是否是奇數(shù)
def isOdd(num):if num % 2 == 0:return Falseelse:return True
result = isOdd(10)
print(result)
?
執(zhí)行到 return 語句, 函數(shù)就會立即執(zhí)行結(jié)束, 回到調(diào)用位置. ?
?上述代碼有另一種寫法:
# 判定是否是奇數(shù)
def isOdd(num):if num % 2 == 0:return Falsereturn True
result = isOdd(10)
print(result)
?如果 num 是偶數(shù), 則進(jìn)入 if 之后, 就會觸發(fā) return False , 也就不會繼續(xù)執(zhí)行 return True
?
?
?
一個函數(shù)是可以一次返回多個返回值的. 使用 , 來分割多個返回值. ?
def getPoint():x = 10y = 20return x, ya, b = getPoint()
?
如果只想關(guān)注其中的部分返回值, 可以使用 _ 來忽略不想要的返回值. ?
def getPoint():x = 10y = 20return x, y_, b = getPoint()
變量作用域?
觀察以下代碼
def getPoint():x = 10y = 20return x, yx, y = getPoint()
在這個代碼中, 函數(shù)內(nèi)部存在 x, y, 函數(shù)外部也有 x, y.
但是這兩組 x, y 不是相同的變量, 而只是恰好有一樣的名字.
變量只能在所在的函數(shù)內(nèi)部生效.
在函數(shù) getPoint() 內(nèi)部定義的 x, y 只是在函數(shù)內(nèi)部生效. 一旦出了函數(shù)的范圍, 這兩個變量就不再生效了.
def getPoint():x = 10y = 20return x, ygetPoint()
print(x, y)
?在不同的作用域中, 允許存在同名的變量
雖然名字相同, 實際上是不同的變量.
x = 20
def test():x = 10print(f'函數(shù)內(nèi)部 x = {x}')test()
print(f'函數(shù)外部 x = {x}')
?
注意:
- 在函數(shù)內(nèi)部的變量, 也稱為 "局部變量"
- 不在任何函數(shù)內(nèi)部的變量, 也稱為 "全局變量"
?
?如果函數(shù)內(nèi)部嘗試訪問的變量在局部不存在, 就會嘗試去全局作用域中查找
x = 20def test():print(f'x = {x}')test()
?
x = 20def test():x = 10test()
print(f'x = {x}')
?
如果是想在函數(shù)內(nèi)部, 修改全局變量的值, 需要使用 global 關(guān)鍵字聲明 ?
x = 20def test():global xx = 10print(f'函數(shù)內(nèi)部 x = {x}')test()
print(f'函數(shù)外部 x = {x}')
?
如果此處沒有 global , 則函數(shù)內(nèi)部的 x = 10 就會被視為是創(chuàng)建一個局部變量 x, 這樣就和全局變量 x 不相關(guān)了. ?
?if / while / for 等語句塊不會影響到變量作用域
換而言之, 在 if / while / for 中定義的變量, 在語句外面也可以正常使用.
for i in range(1, 11):print(f'函數(shù)內(nèi)部 i = {i}')print('-----------------------------')
print(f'函數(shù)外部 i = {i}')
函數(shù)執(zhí)行過程
- 調(diào)用函數(shù)才會執(zhí)行函數(shù)體代碼. 不調(diào)用則不會執(zhí)行.
- 函數(shù)體執(zhí)行結(jié)束(或者遇到 return 語句), 則回到函數(shù)調(diào)用位置, 繼續(xù)往下執(zhí)行.
def test():print("執(zhí)行函數(shù)內(nèi)部代碼")print("執(zhí)行函數(shù)內(nèi)部代碼")print("執(zhí)行函數(shù)內(nèi)部代碼")print("1111")
test()
print("2222")
test()
print("3333")
test()
print('4444')
?
?
這個過程還可以使用 PyCharm 自帶的調(diào)試器來觀察.
- 點擊行號右側(cè)的空白, 可以在代碼中插入 斷點
- 右鍵, Debug, 可以按照調(diào)試模式執(zhí)行代碼. 每次執(zhí)行到斷點, 程序都會暫停下來.
- 使用 Step Into (F7) 功能可以逐行執(zhí)行代碼.
?
?
?好啦,小雅蘭今天的內(nèi)容就到這里啦,和C語言一樣,Python的函數(shù)遞歸的內(nèi)容請小小期待一下小雅蘭的下一篇博客噢,會繼續(xù)加油呀!!!
?