iT邦幫忙

2024 iThome 鐵人賽

DAY 11
0
Python

從概念到應用:Python實戰開發學習之旅系列 第 11

[Day10] 第二週 - 進階工程師的開端 - 模組化程式設計(Modular programming)

  • 分享至 

  • xImage
  •  

今日目標

https://ithelp.ithome.com.tw/upload/images/20240925/20121052Z8l21lusTG.png

今天會講到模組化的概念
我相信如果是開發有一定經歷的工程師
一定對Moudle(模組)開發很熟練~

如果想回顧第二週進階工程師的目標也可以回到這頁喔
[Day8] 第二周 - 脫離新手,朝向工程師之路的開端

如果是新手~也沒關係
今天會以python的模組化來拆解

1.模組是什麼
2.引入模組
3.什麼是套件?
4.專案的運行(模組->套件->專案)

其實可以跟大家概括講解
模組化可以幫住把專注某項功能拆解
管理變得更乾淨喔~!!

今天就開始一一帶大家看下去瞜~

1. 模組是什麼?

不多廢話直接上圖

https://ithelp.ithome.com.tw/upload/images/20240925/20121052ve8vJLdVuQ.png

1.1模組的定義

模組是 Python 文件,包含 Python 代碼,通常一個模組文件是一個 .py 文件。模組可包含函數、類別、變數,並可以被其他模組或包引用。

我們先看下面的文字檔案結構敘述

my_project/
│
├── package_a/
│   ├── __init__.py  # 讓 package_a 成為一個 package
│   ├── module1.py   # 模組1
│   ├── module2.py   # 模組2
│
├── package_b/
│   ├── __init__.py  # 讓 package_b 成為一個 package
│   ├── module1.py   # 模組3
│   ├── module2.py   # 模組4
│
└── main.py          # 主程式

可以想像成一個python file就是一個module

舉個例子: 我們使用訂一個hello world 的function叫做module1.py

def hello_world():
    print("Hello, World!")

1.3模組的命名規則

命名規範:
1.模組名稱應該是簡短且具描述性的,通常使用小寫字母和底線分隔單詞(例如 my_module)。
2.必須以字母或底線開頭,後面可以跟字母、數字或底線。
3.避免使用與內建模組相同的名稱,以免產生衝突。
4.大小寫會視為不同檔案喔mymoudle或是myMoudle
5.python 不需要導出的關鍵字,比如說javascript可能需要export 或是moudle.export來把這個function導出

1.4 模組化優缺點比較

優點 缺點
模組化結構使代碼易於維護和擴展 如果過多拆分模組,會增加複雜性,特別是在大型專案中
每個模組專注於特定功能,增強了代碼的重用性 如果模組之間依賴過多,維護起來會變得困難
可以輕鬆使用 import 來導入各模組,保持主程式的簡潔 需要清楚定義每個模組的責任,避免代碼邏輯過於分散
有助於團隊開發,每個成員可以專注於不同的模組 可能導致過度依賴模組,降低系統的靈活性
減少重複代碼,讓程式更具擴展性與可重用性 新手可能會感到困惑,特別是在理解模組之間的依賴關係上

心得分享
其實我在剛開始寫程式的時候,一直不太理解模組化的用意
會認為一隻程式就可以完成的事情為什麼要拆這麼零碎
還有可能打錯名字導致錯誤的風險!?
/images/emoticon/emoticon19.gif
沒錯!!
會有這種感想是正常的~

不過隨者自我成長後,專案越來越大
開發的功能也越來越多
這樣會造成難以維護(不要說別的工程師維護你的code了,可能過半年後的你...看到自己的code一串也看不懂)
/images/emoticon/emoticon17.gif

這也是為什麼除了模組化程式設計,會讓你的程式碼有系統、有邏輯的切開
延伸概念也可以是: 關聯式資料庫的schema設計、網頁程式設計的component、網頁框架MVC...等

2.引入模組

2.1 import

定義: 我們可以用import這個關鍵字來引入function

import module_name : 我們可以透過這個方式來import 內建模組庫數學運算(math)、系統運算庫(sys)

import math
print(math.sqrt(16))  # 輸出: 4.0

2.2 from...import 的用法

如果你今天要導入其他模組的特定function來使用可以這樣做
from module_name import function_name
這樣可以直接使用該函數,而不需要加上模組名稱。

from math import pi
print(pi)  # 輸出: 3.141592653589793

2.3 使用別名導入模組:

import module_name as alias
這樣可以為導入的模組指定一個別名,方便使用。

舉例比如說大家在看資料處理時,常用的套件numpy,我們可以取名叫做np來省略

import numpy as np
print(np.array([1, 2, 3]))  # 輸出: [1 2 3]

補充:這邊的array是把List這個變成線性代數的1維陣列

3.什麼是套件(Package)?

3.1定義

套件是一個包含多個模組的資料夾,通常資料夾內會有一個 __init__.py 檔案,該檔案告訴Python這是一個套件。

3.2使用情境:

套件適合用於更大且更複雜的應用程序,當你需要管理多個模組時,可以將這些模組組織成套件。

例如,你可能有一個名為 utilities 的套件,內含數學運算和字串操作的模組:

utilities/
    __init__.py
    math_operations.py
    string_operations.py

3.3 init

定義:
__init__.py 是一個特殊的檔案,用來初始化套件。告訴Python該資料夾是一個套件,使其能夠被正確導入和使用。

1.標識套件:當資料夾中包含 init.py,該資料夾會被視為Python的套件,允許其中的模組被導入。如果沒有這個檔案,Python 會認為該資料夾只是普通資料夾,不能作為套件使用。

2.初始化套件:init.py 可以包含套件的初始化代碼。當你導入套件時,Python 會自動執行這些初始化代碼。這可以用來設定套件的一些全域性變數、導入常用的子模組、或者執行某些配置。

3.導入模組:你可以在 init.py 中導入套件中的其他模組,這樣使用者可以直接通過套件名稱導入模組中的內容。例如,使用者可以寫 from utilities import add,而不用明確指定模組名稱。

簡單來說~
init這隻套件中的程式,以package當作是當班來說,init就像是班長或領導一樣
他可以決定或是用來控制底下moudle的功能。

4. 整個模組化的專案怎麼運行?

介紹了這麼多
我們直接來看範例吧~

就以前面的數學工具來舉例
叫出我們最愛的結構化設計圖XDD

4.1 設計成程式碼

需求:
1.需要有一個套件是用來做計算(加跟減)或轉換字母的function
2.main是我們透過python來call主程式點

結構解釋:
1.utilities (Package):
這是我們的套件目錄名稱,包含多個模組。

2.init.py 在此套件中,用來初始化套件並可以在其中進行模組匯入或初始化動作。
init.py:
套件初始化檔案,當導入套件時會自動執行。
它的作用是將套件中的模組匯入,讓外部可以更簡便地使用函數,而無需每次導入具體的模組。

3.math_operations.py:
存放數學運算相關的函數,例如 add() 和 subtract() 函數。

4.string_operations.py:
存放字串處理相關的函數,例如 capitalize_string(),用來將字串的首字母大寫。

https://ithelp.ithome.com.tw/upload/images/20240925/20121052UBiG7kbh4O.png

實作程式碼:/images/emoticon/emoticon13.gif

因為我們開始導入了結構設計,所以會有
5個檔案喔:
1.main.py : 這隻是主程式用來呼叫套件(我們主要call它來運行)
2.utilities資料夾(也就是我們說的套件)
3.init.py
4.math_operations.py
5.string_operations.py

因為我會以main.py來呼叫這個數學的utilities

# main.py

from utilities import add, capitalize_string

print(add(5, 3))  # 輸出: 8
print(capitalize_string("hello"))  # 輸出: Hello

# __init__.py

# 導入模組中的函數,使其在導入套件時可以直接使用
from .math_operations import add, subtract
from .string_operations import capitalize_string

# 可以進行套件初始化的設定
package_name = "Utilities Package"

#string_operations.py
def capitalize_string(s):
    return s.capitalize()

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

4.2 運行結果

https://ithelp.ithome.com.tw/upload/images/20240925/20121052Qq7ZewKaOr.png

這樣我們就可以驗證程式碼無誤喔~!!太棒了

4.3 補充__name__

在 Python 中,name 是一個特殊變數,它用來表示當前模組的名稱。它的值依據模組依照以下來決定:
1.直接執行模組:如果這個模組是直接被執行的(例如使用 python script.py),那麼 name 的值會是 'main'。

2.被匯入模組:如果這個模組是被其他模組匯入的,name 的值會是模組本身的名稱(即 .py 檔案的名稱,去掉 .py)。

至於為什麼會用到呢?我們直接給大家看範例吧!/images/emoticon/emoticon01.gif

https://ithelp.ithome.com.tw/upload/images/20240925/20121052ISzvu5iwly.png

聰明的你應該看出來了
__name__在直接運行的那隻程式,比如說我們是main.py的程式名稱就會被默認帶__name__ = __main__喔

__name__如果在其他檔案中被引入的模組如果是string_operations.py變數就會是string_operations

有沒有發現其中的奧妙?
我們在開發模組(moudle.py)的時候有可能會print()或是執行一些function
主程式在載入的時候這些print()或呼叫會自動執行喔!!!

但~我們不希望在主程式載入時執行到的部分,要怎麼做呢?
我們繼續往下看

https://ithelp.ithome.com.tw/upload/images/20240925/20121052DS1YpRqF5P.png

總結

好啦~
今天我們學會了模組化程式設計的概念
也把python模組的設計拆解出來

大家可以嘗試去實作或是拆解更多的moudle來應用喔!!


上一篇
[Day9] 第二週 - 進階工程師的開端 - 函數(Function)
下一篇
[Day11] 第二週 - 進階工程師的開端 - 標準函式庫的應用
系列文
從概念到應用:Python實戰開發學習之旅12
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言