下面小編就整理了在編程中,比較常用的【函數】0入門到進階的用法。
Python基礎語法 - 專欄鏈接
手把手教你如何入門,如何進階。
目錄
1. 函數的概念
前面學習過的循環是減少代碼重複的一種手段,那麼接下來要學習的函數則是Python裏增強代碼重用性最有力的工具,它的定義是:函數是組織好的、可以重複使用的、用來實現單一功能的代碼。
隨着我們想要實現的功能越來越複雜,代碼可能會有幾百上千行,這樣對寫代碼和讀代碼都是一個挑戰。如果將一個程序用函數拆分成多個獨立的子任務來完成,就會讓代碼結構變得清晰許多。
第1行:def 的意思是定義(define),math 是【函數名】(自己取的),再搭配一個英文括號和冒號,括號裏面的x是參數(參數名也是自己取)。
第2行:def 下一行開始縮進的代碼就是函數要實現的功能,也叫【函數體】。這裏的功能就是:根據x計算出一個值y。
第3行:return 語句是返回的意思,可以指定函數執行完畢後最終會返回什麼值或表達式,否則計算機是無法判斷出函數最終要輸出什麼結果的。
定義函數的語法並不難,但有些注意事項一開始要特別注意才能少踩坑,請你仔細閱讀下。
# 函數名:1. 名字最好能體現函數的功能,一般用小寫字母和單下劃線、數字等組合
# 2. 不可與內置函數重名(內置函數不需要定義即可直接使用)
def math(x):
# 參數:根據函數功能,括號裏可以有多個參數,也可以不帶參數,命名規則與函數名相同
# 規範:括號是英文括號,後面的冒號不能丟
y = 5*x + 1
# 函數體:函數的執行過程,體現函數功能的語句,要縮進,一般是四個空格
return y
# return語句:後面可以接多種數據類型,如果函數不需要返回值的話,可以省略
定義了函數,那怎麼調用呢?
def math(x):
y = 5*x + 1
return y
# math(2)調用math函數,並傳入實參:2。最後賦值給result,並打印結果。
# 因爲math函數 有return返回值,所以result就能夠接收到這個返回值 y。
result = math(2)
print(result)
# 11
2. 函數的形參、實參、默認參數、不定長參數
def math(x,z=3):
y = 5*x + z + 1
return y
result = math(2)
print(result)
# 14
上面例子中,math(x) 中的 x 就是形參,math(2) 中的 2 就是實參。
形參:就是形式參數,它是形式上的,並沒有真正的值。它只是一個標識,表明這裏有個叫 x 的參數。
實參:即實際參數,它是在調用函數時真正傳進去的值。
上面的例子中實參是 2,傳給函數後形參 x 的值就被賦值爲 2 了。
默認參數:直接在定義函數的時候給參數賦值。這裏的 z=3 就是默認參數,直接賦值好的,函數體直接調用的。需要注意的是:默認參數必須放在位置參數之後。
不定長參數:一個星號*
加上參數名,它的返回值也比較特殊:
def menu(*lesson):
return lesson
lessons = menu('python','java','php','c')
#括號裏的這幾個值都會傳遞給參數barbeque
print(lessons)
print(type(lessons))
# ('python', 'java', 'php', 'c')
# <class 'tuple'>
你會發現函數返回的是這樣的結果:('python', 'java', 'php', 'c'),我們用type()函數可以知道這種數據類型叫作元組(tuple)。
比如說我們最熟悉的print()函數,它完整的參數其實是長這樣的:
print(*objects, sep = ' ', end = '\n', file = sys.stdout, flush = False)
可以看到第一個參數objects帶了 * 號,爲不定長參數——這也是爲什麼print()函數可以傳遞任意數量的參數。其餘四個爲默認參數。
3. 函數的作用
在我們沒有學過函數之前,我們計算 y = 5x + 1 可能會像下面這樣寫:
x = 2
y = 5 * x + 1
如果有多個 x 的輸入,你會這樣寫:
x1 = 1
y1 = 5 * x1 + 1
x2 = 2
y2 = 5 * x2 + 1
x3 = 3
y3 = 5 * x3 + 1
...
你應該也注意到了,我們寫了很多相似的重複代碼。而我們學會了函數之後,就可以這樣寫:
def math(x):
y = 5 * x + 1
return y
y1 = math(1)
y2 = math(2)
y3 = math(3)
...
可以看到,代碼非常精簡,需要計算多少次、用多少次函數直接調用就好了。
4. 函數返回多個值、不返回值
函數返回多個值情況:
def shop(money):
if money < 5:
return '飲料'
elif 5 < money < 10:
return '花生', '瓜子'
print(shop(6))
print(type(shop(6)))
# ('花生', '瓜子')
# <class 'tuple'>
# <class 'tuple'>表示返回的數據類型又是我們剛纔提到的元組。在這個例子中,該元組是由兩個元素構成的。
# 元組和列表一樣,可以通過索引來提取當中的某個元素
result = shop(6) # result此時是一個元祖
print(result[0])
print(result[1])
# 花生
# 瓜子
函數不返回值情況:
其實函數的參數和返回值都不是必選項,是可以沒有的。
def say_hello():
print('hello~')
調用上面的 say_hello() 函數會打印出 hello~,只是單純的打印內容而已,不需要參數和返回值。
當然你可以給我們的 say_hello() 函數加功能,對指定的人說你好:
def say_hello(name):
print('hello~' + name)
say_hello('python')
# hello~python
所以,要不要參數完全根據你的需求來定,需要就加,用不到也可以沒有。
5. 函數的變量作用域
在 Python 中變量作用域分爲 全局作用域 和 局部作用域 兩種,兩種作用域下的變量分別是 全局變量 和 局部變量。
對初學者來說,你可以簡單地理解爲:函數內定義的變量是 局部變量,函數外定義的變量是 全局變量。
# 這裏的 rule 在函數外是全局變量
rule = '965 工作制'
def busy_company():
# 這裏的 rule 在函數內是局部變量
rule = '996 工作制'
print('忙碌企業:' + rule)
def common_company():
# 函數內沒有定義 rule,會去全局變量裏找
print('常規企業:' + rule)
busy_company()
common_company()
# 忙碌企業:996 工作制
# 常規企業:965 工作制
這裏要提醒同學注意,調用函數時,Python 會優先在局部作用域內尋找變量,找不到再去外層的全局變量尋找,如果都找不到則報 NameError 的錯誤。
def busy_company():
rule = '996 工作制'
print('忙碌企業:' + rule)
def common_company():
print('常規企業:' + rule)
busy_company()
# 輸出:忙碌企業:996 工作制
common_company()
# 報錯:NameError: name 'rule' is not defined
print(rule)
# 報錯:NameError: name 'rule' is not defined
此時的 rule 屬於busy_company()函數內的局部變量,common_company()函數是無法訪問的。
解決方法:只需要在局部變量前加上 global 關鍵字即可,這樣在全局作用域訪問局部作用域的變量,我們來看個例子:
def busy_company():
global rule # 聲明爲全局變量
rule = '996 工作制'
print('忙碌企業:' + rule)
def common_company():
print('常規企業:' + rule)
busy_company()
# 輸出:忙碌企業:996 工作制
common_company()
# 輸出:常規企業:996 工作制
print(rule)
# 輸出:996 工作制
加了 global 關鍵字後,相當於我們向大家宣佈,自己家裏的東西大家可以一起共用。上面例子中 busy_company() 裏的 rule 就成了全局變量,函數外也能使用,便不會再報錯了。
還有另一種情況,如果在局部作用域修改全局變量的值,也要在函數的局部作用域中的變量前加上 global 關鍵字,我們用代碼來體會一下:
rule = '996 工作制'
def common_company():
global rule # 聲明爲全局變量,沒有聲明,重新賦值無效
rule = '965 工作制'
common_company()
print(rule)
# 輸出:965 工作制
來總結一下:函數內是局部作用域,函數外是全局作用域。局部作用域的變量是局部變量,只能在該函數內使用,全局作用域的變量是全局變量,大家都可以使用。這就像國家規定的 965 工作制是普適的,但有些節奏快的忙碌企業內部會規定 996 工作制,但只在其企業內有效。
如果想讓局部變量變成全局變量也是可以的,只需在使用變量前加上一句 global 變量名 即可。
6. 函數的嵌套
在一個函數內部調用其他函數。
def find_book():
print('查詢所有圖書')
pass # pass 不做任何事情,一般用做佔位語句,測試使用
# 代碼塊
def lend_book():
print('借書')
pass # pass 不做任何事情,一般用做佔位語句,測試使用
# 代碼塊
def return_book():
print('還書')
pass # pass 不做任何事情,一般用做佔位語句,測試使用
# 代碼塊
def welecome():
print('歡迎進入【圖書系統】')
def main():
welecome()
number = input('輸入數字:1.查看所有圖書。2.借書。3.還書。4.退出系統。')
if number == '1': # 根據用戶輸入的數字,調用不同的函數,函數嵌套函數
find_book() # 查看圖書函數
if number == '2':
lend_book() # 借書函數
if number == '3':
return_book() # 還書函數
main()
我們可以看到:在主函數 main() 中調用不同的函數,一個函數 find_book() 負責查看圖書,一個 lend_book() 負責借書,一個return_book() 負責還書,每個函數都有自己的代碼塊,需要用哪個就可以重複調用,達到一個完整的 【圖書系統】。
練習題
同學們,先自覺練習,答案在公衆號,公衆號回覆暗號【答案】即可。
1. 下列代碼的運行結果是?
def func_1():
print("熱乾麪")
def func_2():
food = "螺螄粉"
func_1()
func_2()
func_1()
A. 熱乾麪
螺螄粉
B. 熱乾麪
熱乾麪
C. 螺螄粉
螺螄粉
D. 螺螄粉
熱乾麪
2. 下列代碼中,b 和 d 分別是什麼類型的參數?
def func(a, b):
print(a + b)
# 5
c = 2
d = 3
func(c, d)
A. 形參,實參
B. 形參,形參
C. 實參,實參
D. 實參,形參
3. 下列代碼的運行結果是?
a = 2
def number():
a = 1
number()
print(a)
A. 2
B. 1
C. a
D. None
4. 下列代碼的運行結果是?
def func(a, b, c = 4):
print(a + b + c)
func(1, 2, 3)
A. 5
B. 6
C. 7
D. 8
5. 這段代碼能運行嗎?
def func(a=4, b):
print(a + b)
func(3, 5)
A. 能運行,結果爲8
B. 能運行,結果爲9
C. 能運行,無打印結果
D. 不能運行,報錯
6. 下列代碼的運行結果是?
count = 1
def func():
global count
if count > 0:
count = count + 1
func()
print(count)
A. 0
B. 1
C. 2
D. 3
7. 下列代碼的運行結果是?
a = 1
a = 2
def func(a=4):
print(a)
func(3)
A. 1
B. 2
C. 3
D. 4
8. 做一個簡易的抽獎程序。
# 終端打印結果
開獎倒計時 3
開獎倒計時 2
開獎倒計時 1
************
恭喜小明中獎!
要求:人員名單賦值給列表,傳入該列表到choujiang()函數。
提示1:可利用time模塊的sleep(1)方法,使程序延遲執行,呈現倒計時效果。
提示2:可利用random模塊的choice()方法,隨機從列表中取值。
聯繫我們,一起學Python吧
每週每日,分享Python實戰代碼,入門資料,進階資料,基礎語法,爬蟲,數據分析,web網站,機器學習,深度學習等等。
微信羣(關注「Python家庭」一起輕鬆學Python吧)
QQ 羣(983031854)