從零開始的Python學習Episode 11——裝飾器

微笑小狗發表於2018-10-08

裝飾器

 

裝飾器是用來處理其他函式的函式,主要作用是在不修改原有函式的情況下新增新的功能,裝飾器的返回值也是一個函式物件。

 

簡單的裝飾器

 1 import time
 2 
 3 def show_time(f):
 4     def inner():
 5         start = time.time()
 6         f()
 7         end = time.time()
 8         print(`time: %s`%(end-start))
 9     return inner
10 
11 @show_time
12 def fun1():
13     print(`hello`)
14     time.sleep(1)
15 
16 fun1()
#輸出
#hello
#time: 1.000274896621704

其中@show_time的意思是 fun1 = showtime(fun1) ,作用是在執行原函式add()時,把執行的程式碼轉為inner()函式中的程式碼。

 

帶引數的被裝飾函式

如果被裝飾的函式帶有引數則裝飾函式要帶上引數。

引數個數確定時:

 1 import time
 2 
 3 def show_time(f):
 4     def inner(a,b):
 5         start = time.time()
 6         f(a,b)
 7         end = time.time()
 8         print(`time: %s`%(end-start))
 9     return inner
10 
11 @show_time
12 def fun1(x,y):
13     print(x+y)
14     time.sleep(1)
15 
16 fun1(1,2)
#輸出
#3
#time: 1.0007870197296143

 

引數個數不確定時:

 1 import time
 2 
 3 def show_time(f):
 4     def inner(*args,**kwargs):
 5         start = time.time()
 6         f(*args,**kwargs)
 7         end = time.time()
 8         print(`time: %s`%(end-start))
 9     return inner
10 
11 @show_time
12 def fun1(*args,**kwargs):
13     sum = 0
14     for i in args:
15         sum+=i
16     print(sum)
17     time.sleep(1)
18 
19 fun1(1,2,3,4,5)
#輸出
#15
#time: 1.0009024143218994

 

帶引數的裝飾器

import time
def judge(flag = `False`):
    def show_time(f):
        def inner(*args,**kwargs):
            if flag == `True`:
                start = time.time()
                f(*args,**kwargs)
                end = time.time()
                print(`time: %s`%(end-start))
            else:
                f(*args, **kwargs)
        return inner
    return show_time

@judge(`True`)
def add(*args,**kwargs):
    sum = 0
    for i in args:
        sum+=i
    print(sum)
    time.sleep(1)

@judge()
def multiple(*args,**kwargs):
    sum = args[0]
    for i in args:
        sum*=i
    print(sum)
    time.sleep(1)

add(1,2,3,4,5)
multiple(1,2,3,4,5)
#輸出
#15
#time: 1.0006871223449707
#120

裝飾器的語法允許我們在呼叫時,提供其它引數,比如當@judge()引數為預設的False時,不輸出消耗時間了,當@judge()引數為True時,輸出了消耗時間。這樣實際上是在原有的裝飾器上再加了一層,當我 們使用@judge(‘True’)呼叫的時候,Python能夠發現這一層的封裝,並把引數傳遞到裝飾器的環境中。

 

相關文章