《從零開始的Python筆記》Day#8:Python魔法糖-裝飾器(下)

更新 發佈閱讀 10 分鐘
raw-image

✍️ 常見裝飾器應用範例

計時器

  • 計算函數運行的時間
  • 運算時間對於機器學習模型來說非常重要,這會影響到模型訓練與部署推論的資源需求
import time

def timer_decorator(func):
def wrapper(*args, **kwargs):
start_time = time.time() # 記錄執行開始時間
result = func(*args, **kwargs)
end_time = time.time() # 記錄執行結束時間
print(f"{func.__name__} 執行時間:{end_time - start_time:.4f} 秒")
return result
return wrapper

@timer_decorator
def calculate_sum(n):
return sum(range(n))

result = calculate_sum(1000000)
print(f"結果為:{result}")

# 輸出
calculate_sum 執行時間:0.0253
結果為:499999500000

日誌紀錄器

  • 紀錄函數執行過程的資訊
  • Log紀錄在程式開發過程中很重要,有利於測試以及Debug
def logger_decorator(func):
def wrapper(*args, **kwargs):
print(f"執行 {func.__name__},參數為 args: {args}, kwargs: {kwargs}")
result = func(*args, **kwargs)
print(f"{func.__name__} 執行結束,結果為:{result}")
return result
return wrapper

@logger_decorator
def multiply(a, b):
return a * b

result = multiply(4, 5)

# 輸出
執行 multiply,參數為 args: (4, 5), kwargs: {}
multiply 執行結束,結果為:20

🗂️ 標準裝飾器

Python 提供了一些內建的 標準裝飾器 (Standard Decorators),主要用於支援物件導向程式設計 (Object-Oriented Programming, OOP) 的特性,以及對函數的行為進行修改。常見的標準裝飾器有:

  • @staticmethod
  • @classmethod
  • @property

@staticmethod:定義靜態方法

  • 功能:
    • 將類別中的方法定義為靜態方法,靜態方法不會接收 實例物件 (self) 或 類別物件 (cls) 作為默認參數。
    • 它是一個與類別相關的普通函數,無需存取類別或實例的任何屬性或方法。
  • 用途:
    • 用於封裝一些獨立於實例或類別的邏輯。
    • 節省資源,消除調用 self 和 cls 的需求。
class MathUtility:
@staticmethod
def add(a, b):
"""計算兩數的加總"""
return a + b

@staticmethod
def multiply(a, b):
"""計算兩數的乘積"""
return a * b

# 不需要創建實例,可直接通過類別名調用
print(MathUtility.add(3, 5)) # 8
print(MathUtility.multiply(4, 6)) # 24

@classmethod:定義類別方法

  • 功能:
    • 將方法定義為 類別方法,類別方法會接收 類別本身 (cls) 作為第一個參數,而不是實例對象 (self)。
  • 用途:
    • 可以調用或修改類別層級的屬性。
    • 經常用於創建類別的其他構造方法(例如工廠方法模式)。
class Person:
count = 0 # 類別屬性,記錄已創建的實例數量

def __init__(self, name):
self.name = name
Person.count += 1

@classmethod
def total_instances(cls):
"""返回已創建的實例數量"""
return cls.count

# 創建實例
p1 = Person("Alice")
p2 = Person("Bob")

# 使用類別方法
print(Person.total_instances()) # 2

@property:定義屬性方法

  • 功能:
    • 將方法轉換為類似屬性的行為,允許通過點語法訪問而非直接調用。
    • 屬性方法能確保屬性的封裝性,並能在屬性訪問時動態地進行邏輯處理。
  • 用途:
    • 實現 getter 和 setter,用於保護屬性並提供控制邏輯。
    • 提升封裝性,避免直接操作內部屬性。
class Circle:
def __init__(self, radius):
self._radius = radius # 私有屬性

@property
def radius(self):
"""獲取半徑"""
return self._radius

@radius.setter
def radius(self, value):
"""設置半徑,並確保其大於零"""
if value <= 0:
raise ValueError("半徑必須大於 0")
self._radius = value

@property
def area(self):
"""計算圓的面積"""
return 3.14 * (self._radius ** 2)

# 使用屬性方法
circle = Circle(5)
print(circle.radius) # 5
circle.radius = 10
print(circle.area) # 314.0

比較

raw-image

綜合範例

class BankAccount:
bank_name = "Python Bank" # 類別屬性

def __init__(self, owner, balance=0.0):
self.owner = owner
self._balance = balance # 私有屬性

@staticmethod
def interest_rate():
"""靜態方法:定義固定的利率"""
return 0.05

@classmethod
def change_bank(cls, new_name):
"""類別方法:修改銀行名稱"""
cls.bank_name = new_name

@property
def balance(self):
"""屬性方法:獲取帳戶餘額"""
return self._balance

@balance.setter
def balance(self, amount):
"""屬性方法:設置帳戶餘額,僅允許非負數"""
if amount < 0:
raise ValueError("餘額不能為負")
self._balance = amount

# 使用靜態方法
print(BankAccount.interest_rate()) # 0.05

# 使用類別方法
print(BankAccount.bank_name) # Python Bank
BankAccount.change_bank("CodeBank")
print(BankAccount.bank_name) # CodeBank

# 使用屬性方法
account = BankAccount("Alice", 1000)
print(account.balance) # 1000
account.balance = 1500
print(account.balance) # 1500

# 輸出
0.05
Python Bank
CodeBank
1000
1500
留言
avatar-img
留言分享你的想法!
avatar-img
Ethan的AI學習筆記
6會員
33內容數
我是一個不務正業的資料科學家,從零開始學習的路途上跌跌撞撞,跌過許多坑,也撞過許多牆... 當有人迷失方向時,希望這些筆記可以成為你的指南針。
Ethan的AI學習筆記的其他內容
2025/09/01
Python系列的筆記到這邊就差不多要告個段落,我介紹了基礎語法與進階語法的功能與使用方式。基礎語法對於初學者來說是滿容易理解而且能快速上手的部分,進階語法則是初學者的噩夢,常常讓人難以理解也不知道怎麼使用,不過它卻是讓大家提升程式設計能力的好工具。 一開始大家不需要去死記硬背這些進階語法,只需要大
Thumbnail
2025/09/01
Python系列的筆記到這邊就差不多要告個段落,我介紹了基礎語法與進階語法的功能與使用方式。基礎語法對於初學者來說是滿容易理解而且能快速上手的部分,進階語法則是初學者的噩夢,常常讓人難以理解也不知道怎麼使用,不過它卻是讓大家提升程式設計能力的好工具。 一開始大家不需要去死記硬背這些進階語法,只需要大
Thumbnail
2025/08/23
這篇筆記主要是介紹資料科學家的好朋友:迭代器和生成器! 迭代器與生成器是大家在處理資料以及訓練模型時常常會使用到的工具,請務必熟悉他們的用法!!!
Thumbnail
2025/08/23
這篇筆記主要是介紹資料科學家的好朋友:迭代器和生成器! 迭代器與生成器是大家在處理資料以及訓練模型時常常會使用到的工具,請務必熟悉他們的用法!!!
Thumbnail
2025/08/16
大部分在學習程式語言的人很常會看到或是聽到一個很抽象的詞:物件導向 對於初學者來說,又出現了一個很難以理解的名詞,而且在學習上的確也是很常讓人碰壁的一部分。雖然有著不小的學習障礙,但是對於提升程式設計能力有很大的幫助,因此建議大家可以多點耐心去接觸並且練習如何使用它。
Thumbnail
2025/08/16
大部分在學習程式語言的人很常會看到或是聽到一個很抽象的詞:物件導向 對於初學者來說,又出現了一個很難以理解的名詞,而且在學習上的確也是很常讓人碰壁的一部分。雖然有著不小的學習障礙,但是對於提升程式設計能力有很大的幫助,因此建議大家可以多點耐心去接觸並且練習如何使用它。
Thumbnail
看更多