Python類的動(dòng)態(tài)修改的實(shí)例方法
Python類的動(dòng)態(tài)修改的實(shí)例方法
相信很多朋友在編程的時(shí)候都會(huì)想修改一下已經(jīng)寫好的程序行為代碼,而最常見的方式就是通過(guò)子類來(lái)重寫父類的一些不滿足需求的方法。比如說(shuō)下面這個(gè)例子。
class Dog: def bark(self): print 'Woof!' class Husky(Dog): def bark(self) print 'Howl!'
我們可以用上述方式來(lái)修改我們自己寫的代碼,但是我們應(yīng)該怎么修改第三方代碼呢?當(dāng)然,我們也可以自己編寫一個(gè)子類,調(diào)用子類的實(shí)例對(duì)象來(lái)實(shí)現(xiàn)修改,但是這樣可能會(huì)引入其他一系列問(wèn)題。所以我們得想個(gè)辦法用我們自己的方法替換掉原來(lái)的對(duì)象方法,這就是本文接下來(lái)要介紹的“打補(bǔ)丁”的方式。
給類打補(bǔ)丁
如果我們想新增或是修改對(duì)象的方法的話,最簡(jiǎn)單的方式莫過(guò)于給類打個(gè)補(bǔ)丁了。結(jié)合上面的例子,如果我們想給我們自己的 Dog 類寫一個(gè)新的 howl 方法的話,我們可以定義一個(gè)新的 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
很簡(jiǎn)單吧?但是這里有幾個(gè)問(wèn)題需要我們注意。首先,被修改的類的所有實(shí)例中的方法都會(huì)被更新,所以更新后的方法不僅僅存在于新創(chuàng)建的對(duì)象中,之前創(chuàng)建的所有對(duì)象都會(huì)擁有更新之后的方法,除非只是新增而不是覆蓋掉原來(lái)的方法。第二,你修改或者新增的方法應(yīng)當(dāng)是與對(duì)象綁定的,所以方法的第一個(gè)參數(shù)應(yīng)當(dāng)是被調(diào)用的對(duì)象(在這里就是類的實(shí)例self)。
給類實(shí)例打補(bǔ)丁
單個(gè)對(duì)象也可以在不影響這個(gè)類的其他實(shí)例的情況下打補(bǔ)丁。但是還是有點(diǎn)小技巧的哦!先讓我們看看下面這個(gè)例子。
def herd(self, sheep): self.run() self.bark() self.run() border_collie = Dog() border_collie.herd = herd
然后我們?cè)僭囋囌{(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>
出錯(cuò)啦!引發(fā)錯(cuò)誤的原因就是被調(diào)用的對(duì)象并沒(méi)有作為第一個(gè)參數(shù)傳給我們寫的函數(shù)。當(dāng)然我們可以自己把參數(shù)傳進(jìn)去,但是在這個(gè)替換類方法的場(chǎng)景下并不奏效。解決這個(gè)問(wèn)題的正確方案是用 type 這個(gè)模塊里的 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)和實(shí)例綁定了,大功告成!
總結(jié)
運(yùn)行中替換或者添加方法是非常有用的,比如說(shuō)在單元測(cè)試中,有些負(fù)責(zé)和外界服務(wù)通信的函數(shù)就需要替換掉,方便測(cè)試。這個(gè)技巧不僅很常用,而且在你最終決定要修改代碼之前還可以保持代碼的可維護(hù)性,是一個(gè)非常重要的技巧。
感謝閱讀,希望能幫助到大家,謝謝大家對(duì)本站的支持!
- python 類對(duì)象和實(shí)例對(duì)象動(dòng)態(tài)添加方法(分享)
- 在python的類中動(dòng)態(tài)添加屬性與生成對(duì)象
- Python實(shí)現(xiàn)動(dòng)態(tài)添加類的屬性或成員函數(shù)的解決方法
- Python實(shí)現(xiàn)動(dòng)態(tài)加載模塊、類、函數(shù)的方法分析
- python類的方法屬性與方法屬性的動(dòng)態(tài)綁定代碼詳解
- Python中動(dòng)態(tài)獲取對(duì)象的屬性和方法的教程
- Python實(shí)現(xiàn)動(dòng)態(tài)添加屬性和方法操作示例
- Python實(shí)現(xiàn)動(dòng)態(tài)給類和對(duì)象添加屬性和方法操作示例
相關(guān)文章
python中urllib.unquote亂碼的原因與解決方法
這篇文章主要給大家介紹了python中urllib.unquote亂碼的原因與解決方法,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考價(jià)值,需要的朋友可以參考學(xué)習(xí),下面跟著小編一起來(lái)學(xué)習(xí)學(xué)習(xí)吧。2017-04-04Python中round()函數(shù)實(shí)現(xiàn)數(shù)值的四舍五入
這篇文章主要給大家介紹了關(guān)于Python中round()函數(shù)實(shí)現(xiàn)數(shù)值的四舍五入,round()是python自帶的一個(gè)函數(shù),用于數(shù)字的四舍五入,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-05-05Django框架模板語(yǔ)言實(shí)例小結(jié)【變量,標(biāo)簽,過(guò)濾器,繼承,html轉(zhuǎn)義】
這篇文章主要介紹了Django框架模板語(yǔ)言,結(jié)合實(shí)例形式總結(jié)分析了Django框架中變量,標(biāo)簽,過(guò)濾器,繼承,html轉(zhuǎn)義等相關(guān)模板語(yǔ)言操作技巧,需要的朋友可以參考下2019-05-05Python3中的re.findall()方法及re.compile()
這篇文章主要介紹了Python3中的re.findall()方法及re.compile(),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05python中DataFrame數(shù)據(jù)合并merge()和concat()方法詳解
Pandas提供了很多合并Series和Dataframe的強(qiáng)大的功能,通過(guò)這些功能可以方便的進(jìn)行數(shù)據(jù)分析,下面這篇文章主要給大家介紹了關(guān)于python中DataFrame數(shù)據(jù)合并merge()和concat()方法的相關(guān)資料,需要的朋友可以參考下2022-07-07Python使用pyyaml模塊處理yaml數(shù)據(jù)
這篇文章主要介紹了Python使用pyyaml模塊處理yaml數(shù)據(jù),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-04-04深入解析Python中的descriptor描述器的作用及用法
在Python中描述器也被稱為描述符,描述器能夠?qū)崿F(xiàn)對(duì)對(duì)象屬性的訪問(wèn)控制,下面我們就來(lái)深入解析Python中的descriptor描述器的作用及用法2016-06-06python實(shí)現(xiàn)將pvr格式轉(zhuǎn)換成pvr.ccz的方法
這篇文章主要介紹了python實(shí)現(xiàn)將pvr格式轉(zhuǎn)換成pvr.ccz的方法,涉及Python實(shí)現(xiàn)格式轉(zhuǎn)換的相關(guān)技巧,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-04-04