在python中裝飾器可以為原函式新增一些功能。但如果函式本身是遞迴定義的,則不會僅裝飾最外層,而是在每次遞迴的時候都呼叫裝飾器。這樣會導致原函式無法被直觀的裝飾。
首先定義乙個裝飾器
# 隨便定義乙個裝飾器
defmy_decorator
(fun)
:def
decorator
(*args,
**kwargs)
: fun(
*args,
**kwargs)
return decorator
再用它隨便裝飾乙個遞迴函式
# 隨便裝飾乙個遞迴函式
@my_decorator
defmy_recursion_fun
(num)
:if num ==1:
return
1else
:return
1+ my_recursion_fun(num -
1)
當執行時以上**時
if __name__ ==
'__main__'
: my_recursion_fun(1)
# 沒問題!
my_recursion_fun(2)
# typeerror: unsupported operand type(s) for +: 'int' and 'nonetype'
要解決這個問題,其實十分簡單,只要把遞迴函式的原型函式塞到另乙個不遞迴的函式裡面就行了
修改後
@my_decorator
# 把遞迴函式套起來
defmy_recursion_fun
(num)
:def
_my_recursion_fun
(num)
:if num ==1:
return
1else
:return
1+ _my_recursion_fun(num -1)
return _my_recursion_fun(num)
if __name__ ==
'__main__'
: my_recursion_fun(1)
# 沒問題!
my_recursion_fun(2)
# 沒問題!
做乙個小的計時器來統計遞迴函式執行時間
import time
# 裝飾器, 用來記錄被裝飾函式消耗了多少時間
defmy_timeit
(fun)
:def
decorator
(*args,
**kwargs)
: previous = time.process_time(
) fun(
*args,
**kwargs)
now = time.process_time(
)print
("用時秒"
.format
(now - previous)
)return decorator
@ my_timeit
"""找零兌換問題,來自mooc_資料結構與演算法python版_陳斌_410
coin_value_list為可取硬幣的面額,change為所要求找零的數量
"""def
min_change_rec
(coin_value_list, change)
:def
_min_change_rec
(coin_value_list, change)
: min_coins = change
if change in coin_value_list:
return
1else
:for value in
[coin for coin in coin_value_list if coin <= change]
: num_coins =
1+ _min_change_rec(coin_value_list, change - value)
# 遞迴語句
if num_coins < min_coins:
min_coins = num_coins
return min_coins
return _min_change_rec(coin_value_list, change)
if __name__ ==
'__main__'
: min_change_rec([1
,5,10
,25],
63)# 用時34.515625秒
min_change_rec([1
,5,10
,25],
64)# 用時46.718750秒
可見這個演算法非常的慢(重複計算的原因) 乙個裝飾器裝飾乙個函式
2 如果鍵不存在,則新增到字典中。請使用裝飾器來實現,順便複習下 args和 kwargs的用法 a defselect func def inner args,kwargs if len args 0 if kwargs key in kwargs data print 鍵存在 else func...
裝飾器如何裝飾乙個函式
裝飾器如何裝飾乙個函式?今天番茄加速就來講一下。printstar函式接收乙個函式f,返回值也是乙個函式,所以滿足裝飾器的結構要求,所以printstar是乙個裝飾器。def printstar f def g print 20 f print 20 return g printstar裝飾器實現f...
帶函式的裝飾器 多個裝飾器裝飾乙個函式
一 帶引數的裝飾器 開關 author administrator f true defouter f def wap fun ggdef inner args,kwargs iff print inner before ret fun args,kwargs gg print inner afte...