Python 裝飾器初學筆記

xiaosheng發表於2021-05-08
  • 裝飾器, 不明思議, 作用是來裝飾一個東西的, 注意, 是裝飾, 不是修改. 個人感覺, 就好比化妝, 只是在人本來的面貌上做了一些修飾, 並沒有真正改變人的樣子.

  • 下面以一個簡單的案例來逐步實現裝飾器:
import time

def student():
    print('print student name')

# 現在要為這樣一個函式增加一個輸出時間的功能, 於是我們將程式碼修改成下面的版本
# 版本二
def student():
    print_time()
    print('print student name')

def print_time():
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))

# 這種寫法雖然說實現了上面的功能, 但卻違背了開閉原則, 同時如果有很多個函式都需要輸出時間的功能, 並且萬一輸出時間的函式的函式名稱改變了, 那麼將會很麻煩. 所以繼續改

# 版本三
def student():
    print('print student name')

def print_time(func):
    print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
    func()

print_time(student)

# 這種寫法仍然有邏輯上的問題, 因為列印時間這個功能是屬於 student 這個函式的, 但是上面這種寫法, 是在另外一個函式中寫了這個功能, 並不是 student 本身的功能, 上面這種寫法和下面的寫法個人感覺並沒有什麼區別
print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
student()

# 所以繼續改
# 版本四
def decorator(func):
    def wrapper():
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        func()
    return wrapper

def student():
    print('print student name')

f = decorator(student)
f()

# 這種寫法和版本三的區別並不大, 甚至在呼叫的時候更加麻煩, 所以繼續改
# 版本五 (語法糖)
def decorator(func):
    def wrapper():
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        func()
    return wrapper

@decorator
def student():
    print('print student name')

student()

# 當 student 函式需要傳遞引數的時候的情況
def decorator(func):
    def wrapper(name):
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        func(name)
    return wrapper

@decorator
def student(name):
    print('print student ' + name)

student('xiaosheng')

# 如果要裝飾多個函式, 並且每個函式的引數都不一樣, 那麼程式碼如下
def decorator(func):
    def wrapper(*args):
        print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
        func(*args)
    return wrapper

@decorator
def student(name):
    print('print student ' + name)

student('xiaosheng')
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章