iT邦幫忙

0

python decorator 問題

JK 2018-08-31 20:31:091138 瀏覽
def document_it(func):
    def new_function(*args,**kwargs):
        print('Running function:',func.__name__)
        print('Positional arguments:', args)
        print('leword argument:',kwargs)
        result = func(*args,**kwargs)
        print('Result:',result)
        return result
    return new_function
 def square_it(func):
    def new_function(*arg,**kwargs):
        result= func(*arg,**kwargs)
        return result*result
    return new_function
//執行1
@document_it
@square_it
def add_ints(a,b):
    return a+b
add_ints(3,5)
//執行2
@square_it
@document_it
def add_ints(a,b):
    return a+b
add_ints(3,5)

執行1結果
Running function: new_function
Positional arguments: (3, 5)
leword argument: {}
Result: 64
64
執行2結果
Running function: add_ints
Positional arguments: (3, 5)
leword argument: {}
Result: 8
64

一直搞不懂為何@document_it和@square_it執行順序對調結果會不一樣
我的想法是對調不會有差別,執行解果都長這樣。
Running function: new_function
Positional arguments: (3, 5)
leword argument: {}
Result: 8
8
64
小弟剛接觸python問的 問題很粗淺還請多包涵

1 個回答

2
I code so I am
iT邦研究生 3 級 ‧ 2018-09-01 07:11:11
  1. decorator 會依序執行,也就是在上面的會先被執行,再執行第二個。
  2. @document_it 只印出訊息,未改變 function 內容, @square_it 改變 function 內容為 (a+b) * (a+b)。
  3. 執行一:先執行 @document_it,再執行 @square_it,後者蓋過前者,故 (3+5) * (3+5) = 64
  4. 執行一:先執行 @square_it,再執行 @document_it,後者蓋過前者,故 function 未改變,仍為 (3+5) = 8
看更多先前的回應...收起先前的回應...
JK iT邦新手 5 級 ‧ 2018-09-01 09:29:24 檢舉

result為什麼會被後執行的蓋掉,那兩個result應該都是區域變數吧

function 被換掉,不是 result

froce iT邦大師 1 級 ‧ 2018-09-01 17:06:17 檢舉

應該說有多個 decorator 的狀態,python會依順序套嵌。
不是將add_ints(3, 5)從上往下執行。

所以你看到第一個狀態會是 Running function: new_function
第二個會是: Running function: add_ints

不過有趣的是,這樣的運行行為和下面不一樣。

document_it(square_it(add_ints(3, 5)))

square_it(document_it(add_ints(3, 5)))
JK iT邦新手 5 級 ‧ 2018-09-02 15:06:17 檢舉

python應該有一個執行的順序吧,就是那些值被取出來,哪些值被後來執行的覆蓋掉,看完兩位大大的回覆後還是有點混亂!/images/emoticon/emoticon02.gif

我要發表回答

立即登入回答