# Python函數、模組與套件(5) ### ***數學上的函數是一段算式,而電腦裡的函數是一段程式碼*** ### ***by 幻宇*** 在這一篇,我們會介紹兩個主題,分別是: - 函數(function) - 模組(module)與套件(Package) 他們在某種意義上可以說是親戚,只是在運用上和規模上有所不同 ## 函數(function) 當一段程式碼的使用次數偏多的時候,我們就可以考慮將它變成函數,方便之後要使用時調用,這樣既可以節省空間也可以節省時間。而函數的另一個使用方式是將程式碼進行分段分工,讓程式架構明確,這樣可以方便程式的後續作業,例如除錯和功能擴充 ### 定義函數 函數的建立方式稱為定義(define) ```python def 函數名稱(參數): # 類似數學的f(x)=ax+b 函數主體 return 回傳值 ``` `變數`和`return`在有些情況下是可以省略的 ### 命名規則 - 必須以字母或底線`_`開頭 - 只能包含字母、數字和底線 - 不能使用保留字(例如`if`、`for`、`return`) - 函數名稱區分大小寫 通常我們在命名函數時各單字之間會用底線`_`隔開,例如:`function_add()` ### 參數設定 是否要設定參數取決於你是否要將變數丟進函數來運算 ```python a = 1 b = 1 def add(): c = a + b return c print(add()) # 2 ``` 在上面這個例子中,我們可以發現,我們沒給`add()`任何參數,但依然得到了回傳值`2`,這是因為若沒有設定參數函數會直接調用外部同名變數來進行運算,但反之,若設定了參數則會優先調用參數,例子如下 ```python a = 1 b = 1 def add(a, b): c = a + b return c print(add()) #### 因為沒給參數值所以系統報錯 Traceback (most recent call last): File "c:\Users\hogyu\Desktop\test1.py", line 6, in <module> print(add()) ^^^^^ TypeError: add() missing 2 required positional arguments: 'a' and 'b' #### ``` **補充1**:有一種寫法是`add(a=1,b=1)`,把值和參數寫在一起方便理解 ### 回傳設定 有時函數並不需要回傳數值時,就可以不設定回傳,若無明確`return`,函數默認返回`None` ```python def pri(): print("123") pri() # 123 ``` ### 變數調用 前面提到在特殊情況下,函數可以直接調用外部變數來做使用,而在這裡我們要反其道而行從外部調用內部變數 ```python a = 1 b = 1 def add(a, b): c = a + b return c print(c) ``` 以上為錯誤示範,你啥都調不出來,因為`c`未定義,為什麼會這樣呢? 這裡就要提到**全域變數**和**局域變數**的觀念了 在這裡我們想要調出來的`c`就屬於局域變數,它只生活在函數的小世界裡 而外部的`a`和`b`兩個變數則為全域變數,因此我們只要讓`c`具有全域變數的身分就可以調用了 ```python a = 1 b = 1 def add(a, b): global c # 讓 c 變成全域變數 c = a + b return c print(c) ``` 但當你想說加一個`global`能搞定時,系統又潑了你一桶冷水,為什麼呢? 其實原因很簡單,因為你的函數還沒運行過啊,內部程式碼根本就沒執行過 ```python b = 1 def add(a, b): global c c = a + b return c add(a, b) print(c) # 2 ``` 函數執行過後就可以調用`c`啦 ### 可變與不可變參數 - 不可變類型(如整數、字串)在函數內改變,不影響外部 - 可變類型(如列表、字典)在函數內改變,會影響外部 ```python # 不可變類型 def str_add(str): str = str + "4" str = "123" str_add(str) print(str) # 123 # 可變類型 def list_add(list): list.append(4) numbers = [1, 2, 3] list_add(numbers) print(numbers) # [1, 2, 3, 4] ``` ### 函數進階用法 這部分就先不細講 - 匿名函數(Lambda): 使用`lambda`定義簡短的匿名函數 ``` lambda 參數1, 參數2, ...: 函數主體 ``` 範例: ```python add = lambda x, y: x + y print(add(3, 5)) # 8 ``` - 嵌套函數:函數內可以定義其他函數 - 可以將函數作為參數傳遞或作為回傳值返回 - 遞迴函數: 函數可以調用自身,但必須設置脫離條件避免無窮遞迴 ## 模組(Module)與套件(Package) 在這裡我們只會簡單介紹其概念和一些常用的模組和套件 ### 概念 當我們在開發大型應用程式時,如果沒有適當的組織程式碼,除了會降低開發的效率外,也不易於維護,所以模組(Module)化就顯得相當的重要,讓程式碼能夠透過引用(導入)的方式來重複使用 但是隨著專案模組(Module)的增加,將難以管理及問題的追蹤,這時候就能將模組(Module)打包成套件(Package),利用其階層式的結構來彈性規劃模組(Module) 如果想要知道更詳細的內容可以去看這篇: [解析Python模組(Module)和套件(Package)的概念](https://www.learncodewithmike.com/2020/01/python-module-and-package.html) ### 常見的模組和套件 - `os`:操作系統相關功能(如檔案、目錄操作) - `time`/`datetime`:處理時間和日期 - `random`:生成隨機數或隨機選取 - `keyboard`:偵測鍵盤動作 - `turtle`:2D繪圖 - `pygame`:開發2D遊戲應用 - `pyinstaller`:將Python程式打包成執行檔 這裡只講了幾個對初學者來說比較簡單的模組和套件,之後有空的話,我會在寫相關教學 ### 模組和套件引用(導入)方法 要使用模組或套件就要先確定是否有安裝該模組或套件,有些模組或套件是在安裝Python時就會一起安裝的,而有些則是要自己手動安裝 安裝方法是在終端機中輸入 ``` pip install 模組或套件名稱 ``` 確認安裝好後就可以在程式內引用了 引用(導入)語法 ```python # 導入整個套件或模組 import 套件或模組名稱 # 引用套件內的模組 from 套件 import 模組 # 但如果是直接導入完整的套件 # 就不需要再引用套件內的模組了 ``` ## 總結 Python 的函數、模組與套件的存在不僅讓程式碼更加簡潔,還提高了程式的可讀性與可維護性。透過函數,我們能夠避免重複編寫相同的程式碼,而模組與套件則進一步將功能性程式碼組織起來,讓開發者能以結構化的方式管理程式碼,並在不同專案中重複使用已有的功能,這大幅提高了開發效率。總之,函數、模組與套件的使用是現代程式開發中的核心概念,有助於創建高效且可擴展的應用程式 ## [下一篇](https://hackmd.io/@Huanyu763/Python基礎教學結語) ## [回到主頁](https://hackmd.io/@Huanyu763/home)