1. 程式人生 > >python開發【函數】:裝飾器的誕生

python開發【函數】:裝飾器的誕生

inner 調用 pri 不一致 foo 實現 int 功能 運行

計算函數的運行時間

import time
def bar():
    print("in the bar")
    time.sleep(2)
def foo(func):
    start_time=time.time()
    func()
    end_time=time.time()
    print("in the foo")
    print("該函數運行的時間是%s"%(end_time-start_time))
foo(bar)

雖然已經實現功能,但是改變了函數bar的調用方式,優化後如下:

import time
def bar():
    print
("in the bar") time.sleep(2) def foo(func): start_time=time.time() print("in the foo") return func end_time=time.time() print("該函數運行的時間是%s"%(end_time-start_time)) bar=foo(bar) bar() -------------輸出------------------ in the foo in the bar

總結:函數bar的調用方式未改變,但是與題目要求又不一致,函數遇到return後結束了,未輸出運行函數的時間,繼續優化:

import time
def foo(func):
    def inner():
        start_time=time.time()
        print("in the foo")
        func()
        end_time=time.time()
        print("該函數運行的時間是%s"%(end_time-start_time))
    return inner
@foo#bar=foo(bar)=inner
def bar():
    print("in the bar")
    time.sleep(2)
bar()
-------------輸出------------------ in the foo in the bar 該函數運行的時間是2.0122246742248535

總結:此時裝飾器的雛形已形成,那如果函數帶參數的話,會是怎麽樣了,繼續搞。

import time
def foo(func):
    print("in the foo")
    def inner(*args,**kwargs):
        start_time=time.time()
        print("in the inner")
        func(*args,**kwargs)
        end_time=time.time()
        print("該函數運行的時間是%s"%(end_time-start_time))
    return inner
@foo #bar=foo(bar)=inner
def bar(x,y):
    a=x+y
    print("in the bar")
    print("兩數相加和為%s"%a)
    time.sleep(2)
bar(3,5)
-------------輸出------------------
in the foo #無論函數是否運行,都會默認執行這一步
in the inner
in the bar
兩數相加和為8
該函數運行的時間是2.0000240802764893

總結:無論函數是否執行,都會默認先執行foo函數的,就是這麽給力,那如果函數還有返回值了,怎麽弄了

import time
def foo(func):
    print("in the foo")
    def inner(*args,**kwargs):
        start_time=time.time()
        print("in the inner")
        res=func(*args,**kwargs)
        print("函數的返回值為:%s"%res)
        end_time=time.time()
        print("該函數運行的時間是%s"%(end_time-start_time))
    return inner
@foo #bar=foo(bar)=inner
def bar(x,y):
    a=x+y
    print("in the bar")
    time.sleep(2)
    return a
bar(3,5)
-------------輸出------------------
in the foo
in the inner
in the bar
函數的返回值為:8
該函數運行的時間是2.000295639038086

總結:只是稍加變動就搞定了,那如果裝飾器也帶參數,實現只有在特定情況下計算函數運行的時間,否則不執行

import time
def foo(auth_type):
    print("in the foo")
    def outer(func):
        print("in the outer")
        def inner(*args,**kwargs):
            if auth_type=="run":
                start_time=time.time()
                print("in the inner")
                res=func(*args,**kwargs)
                print("函數的返回值為:%s"%res)
                end_time=time.time()
                print("該函數運行的時間是%s"%(end_time-start_time))
            else:
                print("輸入的auth_type不是run")
        return inner
    return outer
@foo("run") #1、outer=foo("run"),2、bar=outer(bar)=inner
def bar(x,y):
    a=x+y
    print("in the bar")
    time.sleep(2)
    return a
bar(3,5)
-------------輸出------------------
in the foo#只要加了裝飾器,會默認輸出
in the outer#只要加了裝飾器,會默認輸出
in the inner
in the bar
函數的返回值為:8
該函數運行的時間是2.0101609230041504

總結:完美搞定,加了裝飾器的效果後,會首先運行foo("run")得到outer,然後把函數bar當作參數傳入給outer得到outer(bar)運行後得到inner。

python開發【函數】:裝飾器的誕生