更新於 2024/10/20閱讀時間約 9 分鐘

Python 100天-從新手到大師學習筆記Day06:函式與模組的使用


  • 函式的作用:

要寫出高質量的程式碼首先要解決的就是重複程式碼的問題。對於程式碼來說,我們可以將功能封裝到一個稱之為“函式”的功能模組中,在需要使用的地方,我們只需要“呼叫”這個“函式”就可以了。

'''
未使用函式,重複程式碼的案例
Version: Day06
Author: SQA yang
這段程式碼計算三個矩形面積時,每次都重複相同的邏輯
'''

# 計算矩形面積
length1 = 5
width1 = 10
area1 = length1 * width1
print(f"矩形1的面積是 {area1}")

# 計算另一個矩形的面積
length2 = 7
width2 = 3
area2 = length2 * width2
print(f"矩形2的面積是 {area2}")

# 計算第三個矩形的面積
length3 = 9
width3 = 4
area3 = length3 * width3
print(f"矩形3的面積是 {area3}")

未使用函式,重複相同的邏輯的程式碼



  • 定義函式:

在Python中可以使用def關鍵字來定義函式,和變數一樣每個函式也有一個響亮的名字,而且命名規則跟變數的命名規則是一致的。函式執行完成後我們可以透過return關鍵字來返回一個值。

'''
使用函式重購程式碼的案例
消除了重複的程式碼
在這個版本中,calculate_area 函式被引入來避免重複程式碼
這樣可以讓程式更簡潔且易於維護。

Version: Day06
Author: SQA yang
'''

# 使用函式來計算矩形的面積
def calculate_area(length, width):
return length * width

# 計算並輸出矩形面積
length1, width1 = 5, 10
area1 = calculate_area(length1, width1)
print(f"矩形1的面積是 {area1}")

length2, width2 = 7, 3
area2 = calculate_area(length2, width2)
print(f"矩形2的面積是 {area2}")

length3, width3 = 9, 4
area3 = calculate_area(length3, width3)
print(f"矩形3的面積是 {area3}")

重構後使用函式的版本,消除了重複程式碼



  • 函式的引數:

在Python中,函式的引數(即函式的參數)可以有預設值,也支援使用可變引數(接收任意數量的引數)

簡單來講:

  • 函式的預設值:允許我們在定義函式時給參數設置預設值,這樣可以在沒有提供對應參數時使用預設值來執行。
  • 可變引數:允許函式接收任意數量的參數,不需要知道具體的參數數量。



'''
當函式的引數有預設值時,可以選擇不傳入該引數,函式將使用預設值來運行。
'''
def greet(name="Guest"):
print("Hello, " + name)
# 調用函式時不傳參數,使用預設值
greet()  # 輸出: Hello, Guest
# 調用函式時傳入一個參數,覆蓋預設值
greet("Alice")  # 輸出: Hello, Alice

'''
在這個例子中,greet 函式的 name 參數有預設值 "Guest"
所以即使不傳入參數,函式也能正常工作。當傳入 "Alice",函式就會使用這個傳入的值。
'''

函式引數的預設值&可變引數


'''
結合預設值與可變引數
Version: Day06
Author: SQA yang
'''

# 函式 display_info 的第一個參數 name 有預設值 "Guest"
# 而後面的 *args 可以接收多個額外的參數
# 使用 *args 接收任意數量的位置引數。

def display_info(name="Guest", *args):
print(f"Name: {name}") # f"Name: {name}" 中的f是用來表示格式化字串
print("Additional Info:", args)

# 調用函式時只提供名字
display_info("Alice")  
# 輸出:
# Name: Alice
# Additional Info: ()

# 調用函式時提供名字和額外信息
display_info("Alice", 25, "Engineer", "New York")  
# 輸出:
# Name: Alice
# Additional Info: (25, 'Engineer', 'New York')

# 調用函式時不提供名字,使用預設值
display_info(25, "Engineer")  
# 輸出:
# Name: 25
# Additional Info: ('Engineer',)

結合函式預設值與可變引數的應用



  • 用模組管理函式:

對於任何一種程式語言來說,變數、函式會遇到命名衝突這種尷尬的情況。

Python沒有函式過載的概念,那麼後面的定義會覆蓋之前的定義,也就意味著兩個函式同名函式實際上只有一個是存在的。

'''
例如這裡定義了兩個函式foo()
那這樣輸出的結果是什麼呢?

Version: Day06
Author: SQA yang
'''
def foo():
print('hello, world!')

def foo():
print('goodbye, world!')

foo()
#會輸出goodbye, world! 因為後面的函式會覆蓋前面

後面的函式定義會覆蓋之前的定義


在專案中,會遇到由多人協作進行團隊開發的狀況。

團隊中可能有多個程式設計師都定義了名為foo的函式,解決命名衝突其實很簡單,Python中每個檔案就代表了一個模組(module)。在使用函式的時候我們透過import關鍵字匯入指定的模組就可以區分到底要使用的是哪個模組中的foo函式。


module1.py

def foo():
print('hello, world!')

module2.py

def foo():
print('goodbye, world!')
'''
使用import匯入指定模組
這邊匯入的有module1.py和module2.py

Version: Day06
Author: SQA yang
'''

import module1
module1.foo()

import module2
module2.foo()

import module1 as m1
import module2 as m2
m1.foo()
m2.foo()

透過import關鍵字匯入指定的模組



  • 變數的作用域:

看看下面這段程式碼,我們希望透過函式呼叫修改全域性變數a的值,但實際上下面的程式碼是做不到的。

def foo():
a = 200
print(a) # 200


if __name__ == '__main__':
a = 100
foo()
print(a) # 100

做不到呼叫修改全域性變數a的值


在呼叫foo函式後,我們發現a的值仍然是100,這是因為當我們在函式foo中寫a = 200的時候,是重新定義了一個名字為a的區域性變數,它跟全域性作用域的a並不是同一個變數,因為區域性作用域中有了自己的變數a,因此foo函式不再搜尋全域性作用域中的a。修改後的程式碼如下:


'''
使用global關鍵字
來指示foo函式中的變數a來自於全域性作用域

Version: Day06
Author: SQA yang
'''
def foo():
global a
a = 200
print(a)  # 200
if __name__ == '__main__':
a = 100
foo()
print(a)  # 200

使用global關鍵字來指示foo函式中的變數a來自於全域性作用域


在實際開發中,我們應該儘量減少對全域性變數的使用,因為全域性變數的作用域和影響過於廣泛,可能會發生意料之外的修改和使用,除此之外全域性變數比區域性變數擁有更長的生命週期,可能導致物件佔用的記憶體長時間無法被垃圾回收(不會釋放出記憶體空間)。


以上為Python100天從新手到大師的Day06學習筆記。

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.