從R到Python的撞牆期:為什麼我需要學Class?銀行帳戶例子帶我頓悟

更新於 發佈於 閱讀時間約 10 分鐘
raw-image

嘿,如果各位和我一樣是從 R 語言的數據分析世界,踏入 Python 廣闊天地的朋友們,

你是否也和我一樣遇到了那個讓你眉頭深鎖的「老朋友」—— class

你可能已經能熟練地使用 Python 的 def 來定義函數,處理各種資料。但當你看到 class 的語法時,心中是不是也浮現了這樣的OS:

「我感覺 class 就是把好幾個函數放在一起,變成『方法』來用,再給它加了幾個變數當『屬性』。我不懂為什麼要這樣大費周章。如果只是這樣,為什麼我不直接使用函數就好呢?

首先,請接受我的敬意。這個問題絕對不是笨問題,恰恰相反,它是一個極度聰明且一針見血的觀察!它點出了物件導向程式設計(OOP)最核心的「Why」。

沒錯,從結構上看,class 的確是資料(屬性)和功能(方法/函數)的集合體。但它的魔力不在於它「是什麼」,而在於它解決了什麼問題。

今天,就讓我們用你指定的「銀行存提款」例子,來一場深度對談,看看這兩種截然不同的程式碼「世界觀」。

世界觀一:函數為王 (The R Way of Thinking)

在 R 的世界裡,我們習慣於數據和操作是分離的。我們會有一個 data.frame,然後用 dplyrggplot2 這些「工具函數」去操作它。數據是數據,工具是工具。

如果我們用這種思維來打造我們的銀行系統,它大概會長這樣:

# 我們有一個中央資料庫,用字典來管理所有人的錢
bank_database = {
'David': 1000,
'Mary': 5000
}

# 我們打造了兩個「工具」:存款機和提款機
def deposit(account_name, amount, db):
"""
這是一個獨立的存款工具。
你需要告訴它:為誰存、存多少、以及要去哪個資料庫操作。
"""
if amount > 0:
db[account_name] += amount
print(f"操作成功:{account_name} 的新餘額是 ${db[account_name]}")
else:
print("操作失敗:存款金額需為正數。")

def withdraw(account_name, amount, db):
"""
這是一個獨立的提款工具。
同樣,你需要告訴它所有細節。
"""
if db[account_name] >= amount:
db[account_name] -= amount
print(f"操作成功:{account_name} 的新餘額是 ${db[account_name]}")
else:
print(f"操作失敗:{account_name} 餘額不足。")

# --- 開始營業 ---
print(f"初始狀態: {bank_database}")
deposit('David', 500, bank_database)
withdraw('Mary', 1200, bank_database)
print(f"最終狀態: {bank_database}")

這種做法非常直觀,但隨著銀行業務變大,它的「三個致命傷」會逐漸浮現:

  1. 資料和規則是「離婚」的bank_database 這個核心數據,和操作它的規則 (deposit, withdraw) 是完全分開的。這意味著,任何人都可能繞過你的規則。比如,某個新手工程師不小心寫了 bank_database['David'] = -999,整個系統的數據完整性就毀了,而你的檢查規則形同虛設。
  2. 溝通成本極高:每次呼叫函數,你都必須把 db 這個「上下文」傳遞過去。想像一下,如果帳戶資訊不只有餘額,還有信用分數、帳號、開戶分行⋯⋯你的函數參數會變得像一條長長的火車,笨重且難以維護。
  3. 缺乏主體性:程式碼讀起來像是一系列的「指令」。我們作為一個上帝視角的管理者,指揮著各種工具去操作一堆冰冷的數據。

這就是「為何不直接用函數就好」的第一個答案:因為當你需要管理的「狀態」變多、規則變複雜時,單純的函數會讓你的系統變得脆弱且混亂。

世界觀二:物件導向 (The Pythonic Way)

現在,讓我們換一個世界觀。我們不再是從上而下發號施令的管理者,而是成為一個「造物主」。我們先不急著操作數據,而是先「設計」出一個「帳戶」應該是什麼樣子。

這個設計藍圖,就是 class

class BankAccount:
# 這是「創造」帳戶的藍圖,也就是它的「出生證明」
# self 代表「這個物件本身」
def __init__(self, owner_name, initial_balance=0):
# 每個被創造出來的帳戶,都會「記住」自己的主人和餘額
self.owner = owner_name
self.balance = initial_balance
print(f"帳戶 {self.owner} 已建立!")

# 這是每個帳戶「天生就會的技能」
def deposit(self, amount):
if amount > 0:
self.balance += amount # 修改「自己的」餘額
print(f"{self.owner} 操作成功,新餘額是 ${self.balance}")
else:
print("操作失敗:存款金額需為正數。")

def withdraw(self, amount):
if self.balance >= amount:
self.balance -= amount # 修改「自己的」餘額
print(f"{self.owner} 操作成功,新餘額是 ${self.balance}")
else:
print(f"操作失敗:{self.owner} 餘額不足。")

# --- 開始營業 ---
# 我們不再管理一個巨大的字典,而是創造出兩個活生生、獨立的「帳戶物件」
account_david = BankAccount('David', 1000)
account_mary = BankAccount('Mary', 5000)

# 我們不再對數據下指令,而是「請求」物件自己行動
account_david.deposit(500)
account_mary.withdraw(1200)

你看到了嗎?這不僅是寫法的改變,更是思維的躍遷。

  1. 資料和規則「結婚」了:餘額 (balance) 和操作它的方法 (deposit, withdraw) 被封裝BankAccount 這個實體內。數據不再是赤裸裸地暴露在外,而是被自己的規則牢牢保護著。想動我的錢?請通過我的 withdraw 方法來談。
  2. 物件是「有自我意識」的:當我們呼叫 account_david.deposit(500) 時,我們不需要告訴它要操作哪個資料庫。account_david 這個物件自己知道自己的餘額是多少(這就是 self 的魔力)。它管理著自己的狀態,這讓我們的程式碼變得極其乾淨。
  3. 程式碼有了「主體」account_david.withdraw(100) 讀起來不再是冰冷的指令,而是一個有生命的互動:「嘿,David的帳戶,請你為我執行『提款』這個動作。」我們的程式碼開始模擬真實世界,變得更好理解。

結論:所以,到底該用哪個?

讓我們回到最初的問題:「Class 不就只是多了屬性的函數集合,為何不直接用函數就好?」

是的,它的結構是這樣。但它這樣設計的目的,是為了創造出一個個「高內聚、低耦合」的獨立實體。

    • 高內聚:所有相關的東西(數據和規則)都放在一起。
    • 低耦合:每個實體(物件)都盡可能獨立,不與外界有過多牽連。

所以,你的選擇時機非常清晰:

    • 當你需要的是一個「 stateless 的工具」時,請用函數。 例如:寫一個函數計算兩個數字的平均值。它不需要記憶,給它 (2, 4),它就回傳 3,任務結束。
    • 當你需要模擬一個「 stateful 的實體」時,請務必使用 Class。 例如:你要模擬一個遊戲角色(需要記住血量、等級)、一個網路訂單(需要記住商品、金額、送貨地址)、或是一個銀行帳戶(需要記住餘額和戶主)。這些「東西」都有自己的生命週期和需要被記住的狀態。

從 R 到 Python,最大的思維轉變之一,就是從「以數據流為中心」的函數式思維,擴展到「以實體互動為中心」的物件導向思維。

class 不是要取代函數,它是一個更高維度的工具,讓你從一個「寫腳本的工匠」,成長為一個「建構系統的建築師」。希望這篇文章,能為站在十字路口的你,點亮前進的方向。

留言
avatar-img
留言分享你的想法!
avatar-img
慵懶貓系的小墨魚:數據外的日常觀察
0會員
14內容數
小墨魚,一位白天擅長資料分析與統計建模的數據工作者,夜裡則沉浸在書本與文字裡,透過閱讀與寫作與世界對話。工作之餘,也兼職統計家教,協助學生理解複雜的統計概念與軟體操作。這裡記錄我的書評、生活觀察、科技碎念,有時也寫下關於時間與情緒的小片段。願這些文字,成為我們在日常中相遇的溫柔片刻。
2025/09/07
深入淺出 Python 的 @property 裝飾器,瞭解其用法、優缺點以及如何提升程式碼可讀性和維護性,並探討其在屬性控制和資料管理方面的優勢。
Thumbnail
2025/09/07
深入淺出 Python 的 @property 裝飾器,瞭解其用法、優缺點以及如何提升程式碼可讀性和維護性,並探討其在屬性控制和資料管理方面的優勢。
Thumbnail
2025/09/06
深入淺出探討 MySQL 與 PostgreSQL 的架構差異,從資料組織管理的思維角度,幫助你選擇適合專案的資料庫系統。文章比較兩者的優缺點,並以『檔案夾』與『圖書館』的比喻,闡述 MySQL 的直觀與 PostgreSQL 嚴謹的 Schema 架構。
Thumbnail
2025/09/06
深入淺出探討 MySQL 與 PostgreSQL 的架構差異,從資料組織管理的思維角度,幫助你選擇適合專案的資料庫系統。文章比較兩者的優缺點,並以『檔案夾』與『圖書館』的比喻,闡述 MySQL 的直觀與 PostgreSQL 嚴謹的 Schema 架構。
Thumbnail
2025/09/06
深入淺出TOML設定檔格式,探討其用途、發明者Tom Preston-Werner,以及基本語法,包含鍵值對、註解、巢狀結構、物件列表等,並比較其與JSON、YAML、INI的差異,適用於Python, Rust, Hugo等開發者。
Thumbnail
2025/09/06
深入淺出TOML設定檔格式,探討其用途、發明者Tom Preston-Werner,以及基本語法,包含鍵值對、註解、巢狀結構、物件列表等,並比較其與JSON、YAML、INI的差異,適用於Python, Rust, Hugo等開發者。
Thumbnail
看更多
你可能也想看
Thumbnail
常常被朋友問「哪裡買的?」嗎?透過蝦皮分潤計畫,把日常購物的分享多加一個步驟,就能轉換成現金回饋。門檻低、申請簡單,特別適合學生與上班族,讓零碎時間也能創造小確幸。
Thumbnail
常常被朋友問「哪裡買的?」嗎?透過蝦皮分潤計畫,把日常購物的分享多加一個步驟,就能轉換成現金回饋。門檻低、申請簡單,特別適合學生與上班族,讓零碎時間也能創造小確幸。
Thumbnail
Python資料視覺化在數據分析中扮演關鍵角色,透過視覺化捕捉數據模式、趨勢和異常,透過Matplotlib等工具創建專業圖表變相對簡單和高效。
Thumbnail
Python資料視覺化在數據分析中扮演關鍵角色,透過視覺化捕捉數據模式、趨勢和異常,透過Matplotlib等工具創建專業圖表變相對簡單和高效。
Thumbnail
Python擁有便攜性和通用性,適用於多種場景,同時具有全球通用性。Python在科技製造業、資料分析、人工智慧等領域有廣泛應用,對於理工科背景者而言有獨特的優勢。透過在線課程、自學書籍、實作專案,以及參與社群和開源專案,理工背景者可以達成從轉職進入Python程式領域的目標。
Thumbnail
Python擁有便攜性和通用性,適用於多種場景,同時具有全球通用性。Python在科技製造業、資料分析、人工智慧等領域有廣泛應用,對於理工科背景者而言有獨特的優勢。透過在線課程、自學書籍、實作專案,以及參與社群和開源專案,理工背景者可以達成從轉職進入Python程式領域的目標。
Thumbnail
什麼是Python python是電腦程式語言的一種,如同python官方網站上的介紹 "Python是一種程式語,可讓你更快速地工作並更有效的整合系統"。簡單地說,就是你可用python這個程式語言去告訴電腦你想要作什麼,讓電腦來幫你完成你要作的事情。
Thumbnail
什麼是Python python是電腦程式語言的一種,如同python官方網站上的介紹 "Python是一種程式語,可讓你更快速地工作並更有效的整合系統"。簡單地說,就是你可用python這個程式語言去告訴電腦你想要作什麼,讓電腦來幫你完成你要作的事情。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
Python語法包括條件語句、迴圈、函數和變數的使用。條件語句如if、elif和else用於進行條件判斷,for和while是兩種主要的迴圈,def用於定義函數。變數可以被賦予數字或字符串,並可使用類型提示來指定變數的類型。註解可以是單行或多行,並可用於解釋函數或類的用途和作用。
Thumbnail
Python是一種易學且功能強大的程式語言,具有直譯、動態語法等特性,並擁有豐富的標準庫。它在各領域如Web開發、數據科學和人工智慧等得到廣泛應用,並被許多大公司如Google和Facebook等使用。Python還有強大的框架、豐富的交互機能、和龐大的社區。
Thumbnail
Python是一種易學且功能強大的程式語言,具有直譯、動態語法等特性,並擁有豐富的標準庫。它在各領域如Web開發、數據科學和人工智慧等得到廣泛應用,並被許多大公司如Google和Facebook等使用。Python還有強大的框架、豐富的交互機能、和龐大的社區。
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News