初學者指南:深入了解 Python 類別變數

更新日期: 2024 年 10 月 11 日

在學習 Python 的過程中,物件導向程式設計(Object-Oriented Programming, OOP) 是一個重要的概念。

透過 OOP,我們可以使用 類別(Class) 來封裝資料和功能,建立具有特定行為的實體。

在 Python 中,類別變數(Class Variables) 是類別層級的屬性,所有實體共享同一個值。

理解類別變數對於掌握 Python 的物件導向編程非常重要。

本文將為新手詳細介紹 Python 中的類別變數,解釋其作用、如何定義和使用,以及與實體變數的區別。


什麼是類別變數?

類別變數 是定義在類別內且不在任何方法內的變數。

它們屬於類別本身,而非任何特定的實體(Instance)。

所有實體共享同一個類別變數,這意味著對類別變數的修改會影響所有實體。

特點

  • 共享性:所有實體共享同一個類別變數。
  • 定義位置:定義在類別內部,但不在任何方法內。
  • 訪問方式:可以透過類別名或實體名訪問。

類別變數的定義與使用

定義類別變數

在類別內,直接定義變數即可,且不需要使用 self

class 類別名稱:
    類別變數 = 初始值

示例

class Circle:
    pi = 3.14159  # 類別變數

    def __init__(self, radius):
        self.radius = radius  # 實體變數

    def area(self):
        return Circle.pi * self.radius ** 2

在這個例子中,pi 是類別變數,radius 是實體變數。

使用類別變數

circle1 = Circle(5)
circle2 = Circle(10)

print(circle1.area())  # 輸出:78.53975
print(circle2.area())  # 輸出:314.159
  • 說明pi 作為類別變數,被所有實體共享。

類別變數與實體變數的區別

實體變數

  • 定義在 __init__ 方法中,使用 self 關鍵字。
  • 每個實體都有自己的實體變數,彼此獨立。
  • 用於存儲實體的個別狀態。

類別變數

  • 定義在類別內,且不在任何方法內。
  • 所有實體共享同一個類別變數。
  • 用於存儲類別的公共狀態或配置。

比較

項目類別變數實體變數
定義位置類別內,方法外部__init__ 方法內
訪問方式類別名.變數名self.變數名self.變數名
所屬屬於類別,所有實體共享屬於實體,彼此獨立
修改影響影響所有實體只影響特定實體

示例

class Person:
    species = "Homo sapiens"  # 類別變數

    def __init__(self, name):
        self.name = name  # 實體變數
  • species 是類別變數,所有實體共享。
  • name 是實體變數,每個實體都有自己的值。

示例:建立一個簡單的計算器類別

定義類別

class Calculator:
    history = []  # 類別變數,用於存儲計算歷史

    def add(self, a, b):
        result = a + b
        Calculator.history.append(f"{a} + {b} = {result}")
        return result

    def subtract(self, a, b):
        result = a - b
        Calculator.history.append(f"{a} - {b} = {result}")
        return result

    @classmethod
    def show_history(cls):
        for record in cls.history:
            print(record)

使用類別

calc1 = Calculator()
calc2 = Calculator()

calc1.add(5, 3)
calc2.subtract(10, 4)

# 顯示計算歷史
Calculator.show_history()

輸出:

5 + 3 = 8
10 - 4 = 6
  • 說明history 是類別變數,被所有實體共享。

修改和訪問類別變數

訪問類別變數

  • 透過類別名訪問
  print(Calculator.history)
  • 透過實體訪問
  print(calc1.history)

修改類別變數

  • 透過類別名修改
  Calculator.history = ["清除歷史"]
  • 透過實體修改
  calc1.history = ["新的歷史"]

注意:如果透過實體直接賦值,會在該實體中創建一個同名的實體變數,類別變數不受影響。

示例

calc1 = Calculator()
calc2 = Calculator()

# 透過實體修改類別變數
calc1.history = ["新的歷史"]

print("calc1 的 history:", calc1.history)  # 輸出:['新的歷史']
print("calc2 的 history:", calc2.history)  # 輸出:['5 + 3 = 8', '10 - 4 = 6']
print("Calculator 的 history:", Calculator.history)  # 輸出:['5 + 3 = 8', '10 - 4 = 6']
  • 解釋calc1.history = ["新的歷史"]calc1 實體中創建了一個新的實體變數 history,而不影響類別變數。

類別變數的應用場景

  1. 共享狀態或配置
  • 當需要在所有實體之間共享某些資訊時,使用類別變數。
   class Config:
       default_language = "English"
  1. 統計資訊
  • 用於計算創建的實體數量等統計資訊。
   class User:
       user_count = 0

       def __init__(self, name):
           self.name = name
           User.user_count += 1

   user1 = User("Alice")
   user2 = User("Bob")
   print(User.user_count)  # 輸出:2
  1. 緩存或記錄
  • 用於存儲共用的資料,例如緩存結果或記錄日誌。
   class DataFetcher:
       cache = {}

       def fetch(self, key):
           if key in DataFetcher.cache:
               return DataFetcher.cache[key]
           else:
               # 模擬數據獲取
               data = f"Data for {key}"
               DataFetcher.cache[key] = data
               return data

結論

類別變數是 Python 物件導向編程中的重要組成部分,透過它們,我們可以:

  • 共享資料:在所有實體之間共享資訊,避免不必要的重複。
  • 統一配置:集中管理某些全局設定,提升程式的可維護性。
  • 實現統計和記錄:方便地統計實體數量、記錄操作歷史等。

理解並正確使用類別變數,能夠提升程式的結構性和效率,同時避免常見的陷阱,例如不小心在實體中覆蓋類別變數。


進一步學習

  • 實體變數與實體方法:深入理解實體變數和方法,掌握實體的狀態和行為。
  • 類別方法與靜態方法:學習 @classmethod@staticmethod 的用法,拓展類別的功能。
  • 封裝性:瞭解如何使用私有屬性和方法(以雙下劃線 __ 開頭)來實現封裝。
  • 設計模式:學習常見的設計模式,如單例模式、工廠模式等,提升程式設計能力。

Similar Posts