小技巧 裝飾器裝飾乙個遞迴函式

2021-09-28 18:56:50 字數 2625 閱讀 7213

在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...