2016-03-07 51 views
0

我有三個模塊:對班級的Monkeypatching在Python

in_mod.py

class IN(object): 
    def __init__(self): 
     print("i am the original IN") 

module1.py

from in_mod import IN 
class C(object): 
    def __init__(self): 
     cl = IN() 

module2.py

from module1 import C 
class IN2(object): 
    def __init__(self): 
     print("I am the new IN") 

C() 

import in_mod 
in_mod.IN = IN2 
C() 

import module1 
module1.IN = IN2 
C() 

當我使用module1.IN = IN2時,我得到期望的行爲,即猴子修補IN課程並將其替換爲IN2課程。

我想了解in_mod.IN = IN2module1.IN = IN2之間的根本差異是在這種情況下。

我是referencing a相關帖子。

+2

'IN = IN2' * shadows *'module2'內的導入版本,但根本不會改變'module1'。 'module1'內的任何功能仍然會看到以前的版本。你究竟在嘗試修補什麼,以及爲什麼(例如測試)? – jonrsharpe

+0

在第一個例子中,'C2'繼承自'module1.c',但第二個例子中,您從'module1'導入'C2',但從'C'繼承 - 我不知道爲什麼。你能否多說一下「預期的行爲」對你有什麼影響?爲什麼? – senderle

+0

是的,這是測試。我試圖用IN2模擬出IN。我正在嘗試使用'from .. import'導入IN的模塊,我無法更改它。 – Pete

回答

2

from module import IN創建一個局部變量,其引用module.IN; module.ININ是對同一類的兩個單獨的引用。 IN = IN2更改本地參考,但module.IN(由module.C使用)繼續引用相同的類。


UPDATE

在你的編輯,module1.INmodule1命名空間最初一類在in_mod一個全局變量,但是從module命名空間中的全球in_mod.IN不同。更改其值不會影響in_mod。沒有辦法通過module1直接訪問in_mod的名稱空間,因爲您不需要導入整個模塊,只需從模塊獲取一個值。

+0

好的謝謝。我認爲這是我需要的理解。接下來的問題是我如何更改模塊使用的參考。C – Pete

+0

這就是您在第一個示例中所做的:直接指定給'module.IN'。 – chepner

+0

好吧,我重構了這個問題中的代碼,希望能夠使它更加清晰,更接近我在應用程序中的內容。我認爲我現在有一些工作,但我仍然不確定我完全理解爲什麼。你可以看一下嗎?謝謝 – Pete