我正在尝试将一个函数分配给另一个函数,赋值的左侧可以作为String使用。例如,我正在寻找的方法的主体是
def change_function_defintion(name_of_function = 'module1.function1'
, function_object):
# Can I do eval(name_of_function) = function_object ? will that work?
pass
问题:
答案 0 :(得分:3)
我认为使用像Mock这样的模拟库会更好。使用patch
,您可以在上下文管理器或函数的范围内更改函数的行为,然后将其更改回正常状态。例如:
from mock import patch
with patch('module1.function1') as function1:
function1.side_effect = function_object
# Do stuff
如果在function1
块内调用with
,则会将其替换为function_object
。
同样,在函数内修补:
@patch('module1.function1')
def my_test(function1):
function1.side_effect = function_object
# Do stuff
答案 1 :(得分:1)
我的方法:
import importlib
def change_function_defintion(name_of_function = 'module1.function1'
, function_object):
my_mod = importlib.import_module('module1')
setattr(my_mod, function1, function_object)
现在更长的咆哮:
这种方法可能会有效,如果已经在本地命名空间中导入了module1 ,例如,你可以这样做:
>>> a = eval('str')
>>> a
<type 'str'>
>>> a(123)
'123'
在模拟单元测试的环境中,可能有更好的方法。
你可以在这里查看: 对于某些库,http://pycheesecake.org/wiki/PythonTestingToolsTaxonomy#MockTestingTools允许您在单元测试中对模拟对象进行更多控制。
编辑:
你可以这样做,动态导入模块:
>>> import importlib
>>> my_mod = importlib.import_module('mymodule1')
然后,您可以访问模块内的可用函数,或通过eval / getattr获取它们:
my_function = getattr(my_mod,'somefunction')
如果您想将该功能交换为其他功能:
my_mod.functionName = newFunction
答案 2 :(得分:1)
模拟存在一些问题,如果可能,您可以考虑使用不同的测试方法:
答案 3 :(得分:1)
我认为以下内容可以满足您的需求(但您可能需要更强大的解析):
def set_named_fun(funname, fun) :
import sys
modname, funname = funname.rsplit('.')
mod = sys.modules[modname]
setattr(mod, funname, fun)
这里的假设是:
这两个假设略有紧张。必须有很多情况下你可以做到:
import legend
legend.monkey = lambda : "great sage, equal of heaven"
答案 4 :(得分:1)
Python函数装饰器
首先,您所谈论的概念是函数装饰器的概念。函数装饰器通过在函数定义开始之前将其放置在行上而应用于函数定义(符号@
)。它是一种修改函数行为或操作函数组合的工具。这是一个例子
class entryExit(object):
def __init__(self, f):
self.f = f
def __call__(self):
print "Entering", self.f.__name__
self.f()
print "Exited", self.f.__name__
@entryExit # decorator
def func1(): # decorated function
print "inside func1()"
@entryExit
def func2():
print "inside func2()"
我跑
func1()
func2()
我得到了
Entering func1
inside func1()
Exited func1
Entering func2
inside func2()
Exited func2
Python unittest.mock.patch()
补丁充当函数装饰器,类装饰器或上下文 经理。在函数体内或带语句,目标 用新对象修补。当函数/ with语句退出时 修补程序已撤消。
Patch允许您修改with
语句中的函数行为。
这是一个示例,其中patch()用作具有with
语句的上下文管理器。
>>> with patch.object(ProductionClass, 'method', return_value=None)
as mock_method:
... thing = ProductionClass()
... thing.method(1, 2, 3)
...
>>> mock_method.assert_called_once_with(1, 2, 3)
答案 5 :(得分:0)
可以使用“getattr”来使用函数的字符串名称来获取函数(函数是一个对象)。然后你可以在新的命名调用中更改名称并调用/调用其他内容(原始命名函数)。