Python類的動態(tài)修改的實例方法
Python類的動態(tài)修改的實例方法
相信很多朋友在編程的時候都會想修改一下已經(jīng)寫好的程序行為代碼,而最常見的方式就是通過子類來重寫父類的一些不滿足需求的方法。比如說下面這個例子。
class Dog:
def bark(self):
print 'Woof!'
class Husky(Dog):
def bark(self)
print 'Howl!'
我們可以用上述方式來修改我們自己寫的代碼,但是我們應(yīng)該怎么修改第三方代碼呢?當然,我們也可以自己編寫一個子類,調(diào)用子類的實例對象來實現(xiàn)修改,但是這樣可能會引入其他一系列問題。所以我們得想個辦法用我們自己的方法替換掉原來的對象方法,這就是本文接下來要介紹的“打補丁”的方式。
給類打補丁
如果我們想新增或是修改對象的方法的話,最簡單的方式莫過于給類打個補丁了。結(jié)合上面的例子,如果我們想給我們自己的 Dog 類寫一個新的 howl 方法的話,我們可以定義一個新的 howl 函數(shù),像下面的代碼一樣把它添加到我們的類中:
def newbark(self): print 'Wrooof!' def howl(self): print 'Howl!' # Replace an existing method Dog.bark = newbark # Add a new method Dog.howl = howl
很簡單吧?但是這里有幾個問題需要我們注意。首先,被修改的類的所有實例中的方法都會被更新,所以更新后的方法不僅僅存在于新創(chuàng)建的對象中,之前創(chuàng)建的所有對象都會擁有更新之后的方法,除非只是新增而不是覆蓋掉原來的方法。第二,你修改或者新增的方法應(yīng)當是與對象綁定的,所以方法的第一個參數(shù)應(yīng)當是被調(diào)用的對象(在這里就是類的實例self)。
給類實例打補丁
單個對象也可以在不影響這個類的其他實例的情況下打補丁。但是還是有點小技巧的哦!先讓我們看看下面這個例子。
def herd(self, sheep): self.run() self.bark() self.run() border_collie = Dog() border_collie.herd = herd
然后我們再試試調(diào)用新定義的方法:
border_collie.herd(sheep) TypeError: herd() takes exactly 2 arguments (1 given) The problem with the previous code is that the herd is not a bound method, just take a look at the following code: print border_collie.herd <function herd at 0xf9c5f0>
出錯啦!引發(fā)錯誤的原因就是被調(diào)用的對象并沒有作為第一個參數(shù)傳給我們寫的函數(shù)。當然我們可以自己把參數(shù)傳進去,但是在這個替換類方法的場景下并不奏效。解決這個問題的正確方案是用 type 這個模塊里的 MethodType 函數(shù),我們可以看看下面的示例代碼:
import types border_collie = Dog() border_collie.herd = types.MethodType(herd, border_collie) print border_collie.herd <bound method ?.herd of <__main__.Dog instance at 0x23c9518>> border_collie.herd(sheep)
現(xiàn)在我們的方法已經(jīng)和實例綁定了,大功告成!
總結(jié)
運行中替換或者添加方法是非常有用的,比如說在單元測試中,有些負責和外界服務(wù)通信的函數(shù)就需要替換掉,方便測試。這個技巧不僅很常用,而且在你最終決定要修改代碼之前還可以保持代碼的可維護性,是一個非常重要的技巧。
感謝閱讀,希望能幫助到大家,謝謝大家對本站的支持!
相關(guān)文章
Python?實現(xiàn)循環(huán)最快方式(for、while?等速度對比)
這篇文章主要介紹了Python?利用for、while?實現(xiàn)循環(huán)最快方式,文章主要對for、while?等速度對比詳細介紹,具有一定的參考價值?,需要的小伙伴可以參考一下2022-01-01
基于python實現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細介紹了基于python學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-11-11
使用TensorFlow搭建一個全連接神經(jīng)網(wǎng)絡(luò)教程
今天小編就為大家分享一篇使用TensorFlow搭建一個全連接神經(jīng)網(wǎng)絡(luò)教程,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-02-02
Django中使用 Closure Table 儲存無限分級數(shù)據(jù)
對于數(shù)據(jù)量大的情況(比如用戶之間有邀請鏈,有點三級分銷的意思),就要用到 closure table 的結(jié)構(gòu)來進行存儲。這篇文章主要介紹了Django中使用 Closure Table 儲存無限分級數(shù)據(jù),需要的朋友可以參考下2019-06-06

