我想忽略我的代码上的某些装饰器以跳过相关的功能,但仅当作为单元测试的一部分运行时。可以这样做吗?
例如,我有一个函数f,用numba装饰器定义,如下所示:
@numba.jit
def f(a, b):
return a + b
当我运行一个调用上述函数的单元测试时,我不希望发生numba魔法,因为它会减慢速度并导致某些平台出错。是否有可能在某个地方进行设置,告诉鼻子在没有任何numba即时(和/或所有numba)装饰器的情况下运行测试?
仅对于numba,您可以设置一个环境变量(例如.export NUMBA_DISABLE_JIT=1
)来使jit装饰器无操作。
http://numba.pydata.org/numba-doc/dev/user/troubleshoot.html#disabling-jit-compilation
您可以使用可以控制的新装饰器修补装饰器:
import functools
def patch(parent, obj_name, switch_reg, switch_name):
def gen_switcher():
def wrapper(func):
ori_wrapped = ori_decorator(func)
@functools.wraps(func)
def _(*args, **kwargs):
if switch_reg.get(switch_name, False):
func_to_call = func
else:
func_to_call = ori_wrapped
print(func_to_call)
return func_to_call(*args, **kwargs)
return _
return wrapper
ori_decorator = getattr(parent, obj_name)
setattr(parent, obj_name, gen_switcher())
有:
# have to patch the decorator before applying it
import numba
switchs = {}
patch(numba, 'jit', switchs, 'DISABLE_NUMBA_JIT')
@numba.jit
def f(a, b):
return a + b
f(1, 2)
收益率:
CPUDispatcher(<function f at 0x10a5f90d0>)
然后:
# this part could be rewrited as a context manager
switchs['DISABLE_NUMBA_JIT'] = True
f(1, 2)
得到:
<function f at 0x10a5f90d0>
您可以使用自己的装饰器来控制鼻子,保持功能不变。写一个包含这个函数的文件numba.py
:
def jit(func):
return func
并放在你的PYTHONPATH。从该文件所在的目录运行测试,或者在测试文件中执行此操作作为第一行:
import sys
sys.path.insert(0, 'path/to/dir/with/myfile')
或者,您可以将环境变量PYTHONPATH
设置为文件所在的目录。
视窗:
set PYTHONPATH=%PYTHONPATH%;path/to/dir/with/myfile
UNIX / Mac上:
export PYTHONPATH=$PYTHONPATH$:path/to/dir/with/myfile
我将函数分成一个非单元测试的非装饰部分 - 然后让你的真实函数有装饰器并简单地调用辅助函数:
@numba.jit
def f(a, b):
return f_undecorated(a, b)
def f_undecorated(a, b):
return a + b
只为f_undecorated
编写单元测试。