更新於 2024/12/04閱讀時間約 7 分鐘

[Python教學] 進階:生成器與裝飾器

在 Python 中,生成器裝飾器是兩個非常強大的特性,分別讓我們能更高效地處理數據流和更靈活地擴展函數的功能。本篇文章將詳細介紹:

  1. 生成器與 yield 的概念與應用
  2. 裝飾器的原理與應用場景

1. 生成器與 yield

什麼是生成器?

生成器(Generator)是一種特殊的迭代器,允許我們在處理大型數據集時,按需生成數據,而不是一次性將所有數據存儲在記憶體中。這不僅節省了內存,還提升了效率。

生成器是通過函數與 yield 關鍵字實現的,並不像普通函數那樣直接返回結果,而是生成一個「可迭代的對象」。

使用 yield 定義生成器

yield 是生成器的核心。每次執行到 yield 時,函數會暫停執行並返回一個值,直到再次被調用時從暫停的位置繼續執行。

範例:一個簡單的生成器

def simple_generator():
yield 1
yield 2
yield 3

# 使用生成器
gen = simple_generator()
print(next(gen)) # Output: 1
print(next(gen)) # Output: 2
print(next(gen)) # Output: 3

應用場景:生成範圍內的偶數

def even_numbers(n):
for i in range(n):
if i % 2 == 0:
yield i

# 使用生成器
for num in even_numbers(10):
print(num, end=" ") # Output: 0 2 4 6 8

生成器的優點:

  1. 節省記憶體: 不需要一次性存儲所有數據。
  2. 按需生成: 適合處理流式數據或無限序列。

2. 裝飾器的概念與應用

什麼是裝飾器?

裝飾器(Decorator)是 Python 中的一種設計模式,它允許我們在不改變原始函數的情況下,動態地為其增加功能。裝飾器本質上是一個接收函數作為參數的高階函數。

如何定義裝飾器?

基本範例

def my_decorator(func):
def wrapper():
print("這是在函數執行前添加的代碼")
func()
print("這是在函數執行後添加的代碼")
return wrapper

@my_decorator
def say_hello():
print("Hello, World!")

say_hello()

執行結果:

這是在函數執行前添加的代碼
Hello, World!
這是在函數執行後添加的代碼

等價於手動包裝

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

decorated_function = my_decorator(say_hello)
decorated_function()

裝飾器的應用場景

函數執行計時器

import time

def timer(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
def slow_function():
time.sleep(2)
print("函數執行完畢")

slow_function()

權限檢查

def require_login(func):
def wrapper(user, *args, **kwargs):
if not user.get("is_logged_in"):
print("用戶未登入,無法執行此操作")
return
return func(user, *args, **kwargs)
return wrapper

@require_login
def view_profile(user):
print(f"查看用戶 {user['name']} 的資料")

# 測試
user1 = {"name": "Alice", "is_logged_in": True}
user2 = {"name": "Bob", "is_logged_in": False}

view_profile(user1) # 正常執行
view_profile(user2) # 提示未登入

記錄日誌

def log(func):
def wrapper(*args, **kwargs):
print(f"函數 {func.__name__} 被呼叫,參數為: {args}, {kwargs}")
return func(*args, **kwargs)
return wrapper

@log
def add(x, y):
return x + y

print(add(3, 5)) # Output: 8

小結

生成器

  • 使用場景: 範圍生成、大型數據流、流式處理。
  • 優點: 節省記憶體,按需生成。

裝飾器

  • 核心概念: 函數包裝與功能擴展。
  • 應用場景: 記錄日誌、性能分析、權限管理。

Python 的生成器與裝飾器極大提升了程式設計的靈活性與表達能力。掌握這兩個特性,將能更高效地解決複雜問題,並撰寫出簡潔、優雅的程式碼。


課後練習

  1. 生成器練習:
    編寫一個生成器函數 fibonacci(n),生成前 n 個 Fibonacci 數。
  2. 裝飾器練習:
    編寫一個裝飾器 capitalize_return,將原函數的返回值(字串)轉為大寫。

有任何問題或需要更深入的例子,歡迎在評論區留言!

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.