從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
慵懶貓系的小墨魚:數據外的日常觀察
2會員
41內容數
小墨魚,一位白天擅長資料分析與統計建模的數據工作者,夜裡則沉浸在書本與文字裡,透過閱讀與寫作與世界對話。工作之餘,也兼職統計家教,協助學生理解複雜的統計概念與軟體操作。這裡記錄我的書評、生活觀察、科技碎念,有時也寫下關於時間與情緒的小片段。願這些文字,成為我們在日常中相遇的溫柔片刻。
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
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
在 vocus 與你一起探索內容、發掘靈感的路上,我們又將啟動新的冒險——vocus App 正式推出! 現在起,你可以在 iOS App Store 下載全新上架的 vocus App。 無論是在通勤路上、日常空檔,或一天結束後的放鬆時刻,都能自在沈浸在內容宇宙中。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
Thumbnail
vocus 慶祝推出 App,舉辦 2026 全站慶。推出精選內容與數位商品折扣,訂單免費與紅包抽獎、新註冊會員專屬活動、Boba Boost 贊助抽紅包,以及全站徵文,並邀請你一起來回顧過去的一年, vocus 與創作者共同留下了哪些精彩創作。
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還有強大的框架、豐富的交互機能、和龐大的社區。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
Thumbnail
今天來介紹python的函式 函式在python中是非常重要的一環,因為到了後期,程式會越來越複雜。 而函式可以想成是容易管理的小程式,當我們需要使用時,只需呼叫即可。
Thumbnail
在程式中,了解資料型態是相當重要的。 為什麽? 因為許多error,常常都是因為資料型態不正確所導致的。 舉個例子,在python中: a = 1 + 2 print(a) 結果就是3 a = = "1"+"2" print(a) 結果就是12 是不是差很多? 所以今天我來介
Thumbnail
在程式中,了解資料型態是相當重要的。 為什麽? 因為許多error,常常都是因為資料型態不正確所導致的。 舉個例子,在python中: a = 1 + 2 print(a) 結果就是3 a = = "1"+"2" print(a) 結果就是12 是不是差很多? 所以今天我來介
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,
Thumbnail
本文讓我們來淺談一下類別是什麼? 若想看詳細一點的python官方教學可點此連結 Python 的類別(Class)是一種面向物件導向程式設計的概念,讓你能夠創建具有屬性和方法的物件。類別是對現實世界中事物的抽象,它包含數據和操作這些數據的方法。它非常的抽象,想像一個類別就像是一個蛋糕模具,
追蹤感興趣的內容從 Google News 追蹤更多 vocus 的最新精選內容追蹤 Google News