2010-09-11 77 views
7

我在某個模塊中得到了一個函數,我想在運行時爲測試目的重新定義(模擬)。據我所知,函數定義只不過是python中的一個賦值(模塊定義本身是一種正在執行的函數)。正如我所說的,我想在設置測試用例時這樣做,所以要重新定義的函數存在於另一個模塊中。這樣做的語法是什麼? 例如,「模塊1」是我的模塊和「FUNC1」是我的職責,我的測試用例我曾嘗試(沒有成功):如何在python中重新定義函數?

import module1 

module1.func1 = lambda x: return True 
+2

您不需要'lambda'中的'return'。 'module1.func1 = lambda x:True'應該可以工作。 – sastanin 2010-09-13 07:37:04

回答

9
import module1 
import unittest 

class MyTest(unittest.TestCase): 
    def setUp(self): 
     # Replace othermod.function with our own mock 
     self.old_func1 = module1.func1 
     module1.func1 = self.my_new_func1 

    def tearDown(self): 
     module1.func1 = self.old_func1 

    def my_new_func1(self, x): 
     """A mock othermod.function just for our tests.""" 
     return True 

    def test_func1(self): 
     module1.func1("arg1") 

很多模擬的圖書館提供工具來進行這種嘲笑,你應該調查他們,因爲你可能會從他們那裏得到很多幫助。

+0

你知道我是否可以使用閉包重新定義函數? – 2010-09-11 18:51:10

+0

您也可以像您在示例中那樣使用lambda表達式,它不一定是一種方法。 – 2010-09-11 18:59:37

2

只是分配一個新的函數或lambda舊名稱:

>>> def f(x): 
...  return x+1 
... 
>>> f(3) 
4 
>>> def new_f(x): 
...  return x-1 
... 
>>> f = new_f 
>>> f(3) 
2 

它的工作原理也當一個功能是從另一個模塊:

### In other.py: 
# def f(x): 
# return x+1 
### 

import other 

other.f = lambda x: x-1 

print other.f(1) # prints 0, not 2 
+0

正如我所說,該功能是在另一個模塊,檢查我的編輯。 – 2010-09-11 18:46:30

+0

它的工作原理是一樣的。我更新了答案。 – sastanin 2010-09-13 07:34:45

3
import foo 

def bar(x): 
    pass 

foo.bar = bar 
+0

最簡單最好的解決方案。 – Depado 2014-01-31 16:44:56

1

如果你想重新加載到您正在編輯的解釋文件foo.py,你可以做一個簡單的對類型功能和使用的execfile(),但我剛剛得知,這是行不通的沒有的所有功能(可惜)的全局列表,除非有人有更好的主意:在文件foo.py

某處:

def refoo(): 
    global fooFun1, fooFun2 
    execfile("foo.py") 

在Python解釋器:

refoo()#現在你已經把最新的編輯從foo.py

2

使用REDEF:http://github.com/joeheyming/redef

import module1 
from redef import redef 

rd_f1 = redef(module1, 'func1', lambda x: True) 

當rd_f1超出範圍或被刪除,func1將回到正常狀態

+0

我認爲ref-counting scope是一個CPython事物,而這種事情在其他平臺(PyPy,Jython,IronPython)上不起作用。 – leewz 2014-04-14 19:14:36

+0

所有redef所做的都是用新函數/屬性包裝一個函數或屬性。當對象超出作用域時,將調用__delete__函數,該函數將函數聲明恢復爲使用舊的函數/屬性。這不是一個重新計數範圍的東西。 – 2014-04-14 22:55:40

+0

但是當「對象超出範圍時發出信號」的想法取決於CPython ref-counting,不是嗎?例如,在PyPy中,當文件對象的變量超出作用域時,對象不會立即被垃圾收集,因此文件在收集器決定之前不會關閉。 – leewz 2014-04-14 22:58:52