如何制作一个虚拟的无操作 @jit 装饰器?

Posted

技术标签:

【中文标题】如何制作一个虚拟的无操作 @jit 装饰器?【英文标题】:How do I make a dummy do-nothing @jit decorator? 【发布时间】:2020-01-06 12:39:03 【问题描述】:

我希望 numba 成为一个可选依赖项,这样如果安装它就快,否则就慢。所以当没有安装 numba 时,我希望 @njit 成为一个什么都不做的虚拟装饰器。

如果我关注these directions 并使用:

def njit(func):
    return func

然后,当装饰器被称为 @njit(cache=True, nogil=True) 时,我收到以下错误:

TypeError: njit() got an unexpected keyword argument 'cache'

如果我尝试捕获 args 并使用忽略它们

    def njit(func, *args, **kwargs):
        return func

然后我得到:

missing 1 required positional argument: 'func'

我如何制作一个什么都不做并忽略 kwargs 的虚拟装饰器?

【问题讨论】:

Decorators with parameters?的可能重复 【参考方案1】:

将带有参数的装饰器想象成装饰器工厂,它们返回一个装饰器。这边

def decorator(func):
    return func

上面是一个装饰器,现在带有参数

def decorator_factory(a,b,c):
    def decorator(func):
        return func
    return decorator

内部decorator 可以访问a,b,c 参数,因为它是一个闭包。希望对你有帮助


所以可以定义为:

def njit(cache, nogil):
    def decorator(func):
        return func 
    return decorator

【讨论】:

是的,可以修复它。 def njit(*args, **kwargs): def decorator(func): return func return decorator @endolith:只有当你总是这样做 @njit() 而从不 @njit。如果你做过@njit,它会默默地做错事。【参考方案2】:

如果您想节省一些时间并能够对所有 numba 装饰器执行相同的操作,请尝试 numbasub。它准确地提供了您所要求的内容,您可以将其应用到您想要的任何项目中。

【讨论】:

不过,这只是另一个依赖项? 真的。这是一个非常轻的依赖关系,因为它本身没有依赖关系。另外,它涵盖了很多令人讨厌的情况,例如,如果在代码中的某处导入了 numba 类型,则必须一个一个地模拟它们。但是如果只需要为几个装饰器创建虚拟对象,那可能就有点过头了(它甚至在自述文件中提到过)。

以上是关于如何制作一个虚拟的无操作 @jit 装饰器?的主要内容,如果未能解决你的问题,请参考以下文章

如何制作函数装饰器并将它们链接在一起?

python之路--装饰器函数

编程模式之Go语言如何实现装饰器

Python虚拟机函数机制之闭包和装饰器

python进阶之装饰器之2.定义一个可接受参数的装饰器如何定义一个属性可由用户修改的装饰器定义一个能接受可选参数的装饰器

如何使用可选参数构建装饰器? [复制]