要寫出高質量的程式碼首先要解決的就是重複程式碼的問題。對於程式碼來說,我們可以將功能封裝到一個稱之為“函式”的功能模組中,在需要使用的地方,我們只需要“呼叫”這個“函式”就可以了。
'''
未使用函式,重複程式碼的案例
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()
看看下面這段程式碼,我們希望透過函式呼叫修改全域性變數a
的值,但實際上下面的程式碼是做不到的。
def foo():
a = 200
print(a) # 200
if __name__ == '__main__':
a = 100
foo()
print(a) # 100
在呼叫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
在實際開發中,我們應該儘量減少對全域性變數的使用,因為全域性變數的作用域和影響過於廣泛,可能會發生意料之外的修改和使用,除此之外全域性變數比區域性變數擁有更長的生命週期,可能導致物件佔用的記憶體長時間無法被垃圾回收(不會釋放出記憶體空間)。
以上為Python100天從新手到大師的Day06學習筆記。