2013-10-19 55 views
1

比方說,我想暫時通過應用一些公式something.action這樣更換一類的一些行動,有什麼辦法可以回到原來的功能?

something.action = apply(something.action) 

後來,我想通過做這樣的事情到原來的操作方法適用回到實例something

something.action = ... 

我該如何做到這一點?

+0

您是否確定手頭的問題無法使用繼承/包裝而不是修補(混淆)對象來解決? –

回答

8

我想你可以簡單地保存原有的功能和寫入

tmp = something.action 
something.action = apply(something.action) 

然後,後來

something.action = tmp 

例子:

class mytest: 
    def action(self): 
     print 'Original' 

a = mytest() 
a.action() 

tmp = a.action 

def apply(f): 
    print 'Not the ', 
    return f 

a.action = apply(a.action) 
a.action() 

a.action = tmp 
a.action() 

這給

$ python test.py 
Original 
Not the Original 
Original 
要做到這一點
+0

我嘗試過,但我認爲通過做'something.action = apply(something.action)',因爲tmp被綁定到something.action,tmp也會改變爲新的應用操作。 – chanpkr

+3

@Chan不會,只要「應用」做它應該做的事情 - 創建something.action的副本並返回它。如果它將「就地」動作更改,而不是將其錯誤地用作函數而不是就地過程,那麼整個信息都會丟失,因此您需要複製函數:http://stackoverflow.com/questions/6527633/我怎麼能做一個在python中的函數的深層拷貝 – lejlot

+0

@lejlot哦..那麼你如何複製一個函數呢? – chanpkr

0

最好的辦法是存儲在同一個對象的動作,但有不同的名稱:

something._old_action = something.action 
something.action = apply(something._old_action) # this way you can still use it 
something.action = lambda x: print(x)   # or you can ignore it completely 
do_some_stuff() 
something.action = something._old_action 

請注意,我們存儲在該對象的舊動作,我們可以使用它。通過使用_開始名稱,我們通知該屬性是私有的(純粹是一種慣例,但它是我們在Python中所有的)

0

這樣的事情怎麼樣,而不是搞亂你的對象?

class Original(object): 
    def __init__(self): 
     self.x = 42 

    def hello(self): 
     print self.x 

class OriginalWrapper(Original): 
    def __init__(self, original): 
     self.__class__ = type(original.__class__.__name__, 
           (self.__class__, original.__class__), {}) 
     self.__dict__ = original.__dict__ 

    def hello(self): 
     print self.x + 10 

original = Original() 
original.hello() #42 
wrapped = OriginalWrapper(original) 
wrapped.hello() #52 
相關問題