第九關:函數 - 0入門到進階(附練習題) | Python基礎語法

下面小編就整理了在編程中,比較常用的【函數】0入門到進階的用法。

Python基礎語法 - 專欄鏈接

手把手教你如何入門,如何進階。

目錄

1.  函數的概念

2.  函數的形參、實參、默認參數、不定長參數

3.  函數的作用

4.  函數返回多個值、不返回值

5.  函數的變量作用域

6.  函數的嵌套

練習題

聯繫我們,一起學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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章