1. 程式人生 > >Python3-裝飾器 裝飾器

Python3-裝飾器 裝飾器

裝飾器(語法糖)

裝飾器的本質:一個閉包函式

裝飾器的功能:在不修改原函式及其呼叫方式的情況下對原函式功能進行擴充套件

例子1.

給hahaha函式加上一個timmer(計算函式執行時間)的功能。

import time
def timmer(func):
    #函式名可以當做函式的引數
    def inner():
        start = time.time()
        func()
        end = time.time()
        print(start - end)
    return inner

# 語法糖
@timmer       # @把hahaha函式名作為引數傳到timmer(),執行了一次, 然後進行了重新賦值 hahaha 
= timmer(hahaha) --> inner() def hahaha(): time.sleep(0.1) print('aaaa') # time(hahaha) 不能改變這個函式的呼叫方式 # 也不能修改原始碼 # hahaha = timmer(hahaha) timmer(hahaha)函式的執行結果返回 inner函式的記憶體地址,然後賦值給hahaha # hahaha() 就等同於 inner() hahaha()

裝飾器的設計模式:開放封閉原則

開放:對擴充套件是開放的

封閉:對修改是封閉的

 

剛剛我們討論的裝飾器都是裝飾不帶引數的函式,現在要裝飾一個帶引數的函式怎麼辦?

import time

def timer(func):
    def inner(*args, **kwargs):
        start_time = time.time()
        func(*args, **kwargs)
        end_time = time.time()
        print(end_time - start_time)
    return inner

@timer
def func1(a):
    time.sleep(2)
    print(a)

func1('bb')

 

帶引數的裝飾器

def outer(flag):
    def timer(func):
        def inner(
*args, **kwargs): if flag: print('執行函式之前要做的') func(*args, **kwargs) if flag: print('執行函式之後要做的') return inner return timer @outer(True) def func2(mode): print(111, mode) func2('rrr')

 

多個裝飾器裝飾同一個函式

有些時候,我們也會用到多個裝飾器裝飾同一個函式的情況。

def wrapper1(func):
    def inner():
        print('wrapper1 ,before func')
        func()
        print('wrapper1 ,after func')
    return inner

def wrapper2(func):
    def inner():
        print('wrapper2 ,before func')
        func()
        print('wrapper2 ,after func')
    return inner

@wrapper2
@wrapper1
def f():
    print('in f')

f()

輸出:

wrapper2 ,before func
wrapper1 ,before func
in f
wrapper1 ,after func
wrapper2 ,after func