Python類的動(dòng)態(tài)修改的實(shí)例方法
Python類的動(dòng)態(tài)修改的實(shí)例方法
相信很多朋友在編程的時(shí)候都會(huì)想修改一下已經(jīng)寫(xiě)好的程序行為代碼,而最常見(jiàn)的方式就是通過(guò)子類來(lái)重寫(xiě)父類的一些不滿足需求的方法。比如說(shuō)下面這個(gè)例子。
class Dog:
def bark(self):
print 'Woof!'
class Husky(Dog):
def bark(self)
print 'Howl!'
我們可以用上述方式來(lái)修改我們自己寫(xiě)的代碼,但是我們應(yīng)該怎么修改第三方代碼呢?當(dāng)然,我們也可以自己編寫(xiě)一個(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 類寫(xiě)一個(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ù)傳給我們寫(xiě)的函數(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爬蟲(chóng)請(qǐng)求頁(yè)面urllib庫(kù)詳解
這篇文章主要介紹了python爬蟲(chóng)請(qǐng)求頁(yè)面urllib庫(kù)詳解,python3將urllib和urllib2模塊整合并命名為urllib模塊,urllib模塊有多個(gè)子模塊,各有不同的功能,需要的朋友可以參考下2023-07-07
Python?實(shí)現(xiàn)循環(huán)最快方式(for、while?等速度對(duì)比)
這篇文章主要介紹了Python?利用for、while?實(shí)現(xiàn)循環(huán)最快方式,文章主要對(duì)for、while?等速度對(duì)比詳細(xì)介紹,具有一定的參考價(jià)值?,需要的小伙伴可以參考一下2022-01-01
基于python實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了基于python學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Python繪圖系統(tǒng)之繪制散點(diǎn)圖,極坐標(biāo)和子圖
這篇文章主要為大家詳細(xì)介紹了如何基于Python實(shí)現(xiàn)一個(gè)繪圖系統(tǒng),可以支持繪制散點(diǎn)圖,極坐標(biāo)和子圖,文中的示例代碼講解詳細(xì),感興趣的可以了解下2023-09-09
使用TensorFlow搭建一個(gè)全連接神經(jīng)網(wǎng)絡(luò)教程
今天小編就為大家分享一篇使用TensorFlow搭建一個(gè)全連接神經(jīng)網(wǎng)絡(luò)教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-02-02
Django中使用 Closure Table 儲(chǔ)存無(wú)限分級(jí)數(shù)據(jù)
對(duì)于數(shù)據(jù)量大的情況(比如用戶之間有邀請(qǐng)鏈,有點(diǎn)三級(jí)分銷的意思),就要用到 closure table 的結(jié)構(gòu)來(lái)進(jìn)行存儲(chǔ)。這篇文章主要介紹了Django中使用 Closure Table 儲(chǔ)存無(wú)限分級(jí)數(shù)據(jù),需要的朋友可以參考下2019-06-06

