一共三個文件python
a.py內容是函數
print('被導入')spa
x = 1對象
b.py內容是import
import a變量
a.x = 2引用
c.py內容是方法
import aim
import bimg
print(a.x)
如今運行c文件,這個結果出乎不少人的意料大部分python人員都猜不對,結果是
在c文件裏面無論是先導入a仍是先導入b,
一、能夠發現a模塊被兩個地方導入了,可是隻打印一次 「被導入」。
二、打印x的結果都是2。
不光是本身的文件如此,導入庫文件也是同樣。因此這就是猴子補丁能實現的緣由。
二、再多想一下,爲何要面向對象了,不面向對象,直接模塊加全局變量,會形成多個地方全局變量互相干擾。有了類,類自然就是多實例,類的全部實例就像是無數個全局變量互不干擾的複製模塊。
2.1不用面向對象也能夠實現多實例,原來是狗寫成全局變量了,須要改爲從函數return一隻狗,而後有個吃翔的函數,把這個return出來的狗傳給這個函數,因此形式是
eat(dog,sheet)
2.2用面向對象,那麼就不是狗模塊了,有個狗類,狗吃翔變成了
dog = Dog()
dog.eat(sheeet)
那麼多個狗就實例化屢次,每一個狗 吃了多少翔 體重變化了多少,都是徹底獨立的。
2.1的面向過程模擬多實例,須要在類外傳入和保存不少狗的屬性和狀態,多個函數使用同一個類型的傳參,很頻繁,不是很容易看懂,例如a函數的第一個參數和b函數的第一個參數是表明同一個東西好比狗的名字,有的人在a函數寫dog_name,在b
函數寫name,真的不容易看出來他們的關聯。若是是面向對象,那是很直觀的,a方法和b方法都是引用self.name。
扯遠了從模塊導入機制 到了猴子補丁 面向過程 面向對象了。
三、把b文件改爲這樣,name運行c會獲得什麼呢。
import afrom a import xx = 2由第三個例子可見,猴子補丁可不是亂打,地方打錯了,就不會生效。主要是要找到你經常使用那個模塊的什麼函數或者類,patch與那個引用同一個模塊的模塊。打補丁時候必定要搞清楚from xx import yy和import xx.yy的區別,區別至關大。