裝飾器給我們帶來高效的編程,但也會產生一些問題,而這些問題又容易被我們大家忽視。
裝飾器產生的副作用
在Python世界里,一切皆對象,所以函數也是對象,函數有一些內置屬性,例如:__name__、 __module__ 、__doc__ 和__dict__等。
如果使用裝飾器修飾函數,那么函數的內置屬性值會發生變化,這將不利于調試,定位bug位置,這就是裝飾器產生的副作用!
結合示例了解裝飾器的副作用:
定義了兩個測試函數,功能一致,函數sum_test1用aop裝飾器修飾(這里裝飾器沒有任何功能操作),函數sum_test2沒有裝飾器修飾。
看代碼執行結果:
你會發現:被裝飾器修飾的函數,屬性內容發生了改變,sum_test1函數的__name__、__doc__等等屬性值都變成了裝飾器函數對應屬性值,而沒有裝飾的sum_test2函數顯示正常!
更大的問題了,被裝飾器修飾的多個函數,其函數屬性值都會變成裝飾器函數內容,多個不同的函數,其屬性值是相同的,這非常不利于調試,定位程序bug。
以上就是裝飾器產生的副作用!
如何消除裝飾器的副作用
使用functools模塊提供 wraps和update_wrApper 方法能夠修正函數內置屬性值,消除裝飾器副作用
update_wrapper 使用示例:
看代碼執行結果:
wraps使用示例:
update_wrapper和wraps方法的功能是一樣的,只不過wraps是使用partial()對update_wrapper進一步封裝得到的,所以推薦使用wraps方法!
總結
使用裝飾器給我們帶來高效的編程,但是裝飾器會產生一個容易讓人忽視的副作用:不利于調試,定位程序bug。
使用functools模塊提供 wraps和update_wrapper 方法,消除Python裝飾器副作用;而且使用update_wrapper和wraps是一個好的編程習慣!