我在某個模塊中得到了一個函數,我想在運行時爲測試目的重新定義(模擬)。據我所知,函數定義只不過是python中的一個賦值(模塊定義本身是一種正在執行的函數)。正如我所說的,我想在設置測試用例時這樣做,所以要重新定義的函數存在於另一個模塊中。這樣做的語法是什麼? 例如,「模塊1」是我的模塊和「FUNC1」是我的職責,我的測試用例我曾嘗試(沒有成功):如何在python中重新定義函數?
import module1
module1.func1 = lambda x: return True
我在某個模塊中得到了一個函數,我想在運行時爲測試目的重新定義(模擬)。據我所知,函數定義只不過是python中的一個賦值(模塊定義本身是一種正在執行的函數)。正如我所說的,我想在設置測試用例時這樣做,所以要重新定義的函數存在於另一個模塊中。這樣做的語法是什麼? 例如,「模塊1」是我的模塊和「FUNC1」是我的職責,我的測試用例我曾嘗試(沒有成功):如何在python中重新定義函數?
import module1
module1.func1 = lambda x: return True
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")
很多模擬的圖書館提供工具來進行這種嘲笑,你應該調查他們,因爲你可能會從他們那裏得到很多幫助。
你知道我是否可以使用閉包重新定義函數? – 2010-09-11 18:51:10
您也可以像您在示例中那樣使用lambda表達式,它不一定是一種方法。 – 2010-09-11 18:59:37
只是分配一個新的函數或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
正如我所說,該功能是在另一個模塊,檢查我的編輯。 – 2010-09-11 18:46:30
它的工作原理是一樣的。我更新了答案。 – sastanin 2010-09-13 07:34:45
如果你想重新加載到您正在編輯的解釋文件foo.py,你可以做一個簡單的對類型功能和使用的execfile(),但我剛剛得知,這是行不通的沒有的所有功能(可惜)的全局列表,除非有人有更好的主意:在文件foo.py
某處:
def refoo():
global fooFun1, fooFun2
execfile("foo.py")
在Python解釋器:
refoo()#現在你已經把最新的編輯從foo.py
使用REDEF:http://github.com/joeheyming/redef
import module1
from redef import redef
rd_f1 = redef(module1, 'func1', lambda x: True)
當rd_f1超出範圍或被刪除,func1將回到正常狀態
我認爲ref-counting scope是一個CPython事物,而這種事情在其他平臺(PyPy,Jython,IronPython)上不起作用。 – leewz 2014-04-14 19:14:36
所有redef所做的都是用新函數/屬性包裝一個函數或屬性。當對象超出作用域時,將調用__delete__函數,該函數將函數聲明恢復爲使用舊的函數/屬性。這不是一個重新計數範圍的東西。 – 2014-04-14 22:55:40
但是當「對象超出範圍時發出信號」的想法取決於CPython ref-counting,不是嗎?例如,在PyPy中,當文件對象的變量超出作用域時,對象不會立即被垃圾收集,因此文件在收集器決定之前不會關閉。 – leewz 2014-04-14 22:58:52
您不需要'lambda'中的'return'。 'module1.func1 = lambda x:True'應該可以工作。 – sastanin 2010-09-13 07:37:04