为什么“joblib.delayed”不能用作装饰器?

Gra*_*her 5 python decorator python-2.7 python-decorators joblib

该包joblib有一个函数delayed,它捕获传递给该函数的参数。它可以像这样使用:

from joblib import delayed

def f(n):
    return n**2

delayed(f)(2)
# (<function f at 0x7f939eb3fe60>, (2,), {})
h = delayed(f)
h(2)
# (<function f at 0x7f939eb3fe60>, (2,), {})
Run Code Online (Sandbox Code Playgroud)

后一种用法让我认为它可以像任何其他装饰器一样使用。它的文档支持这一点:

joblib.delayed(函数, check_pickle=True)

装饰器用于捕获函数的参数。

但是,这失败了:

from joblib import delayed

@delayed
def g(n):
    return n**2

# Traceback (most recent call last):
#  File "<stdin>", line 1, in <module>
#  File "/usr/lib/python2.7/dist-packages/joblib/parallel.py", line 158, in delayed
#    pickle.dumps(function)
#  File "/usr/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
#    raise TypeError, "can't pickle %s objects" % base.__name__
#TypeError: can't pickle function objects
Run Code Online (Sandbox Code Playgroud)

我尝试过这个Python 2.7.12

Kri*_*ris 1

看起来这是一个命名空间问题,这导致joblib.delayed尝试腌制输出函数(而不是原始函数)。

我没有研究过 joblib 代码,但你提出的方法就是这样做的方法:

import joblib

def _func(*args, **kwargs):
    'your code here'

func = joblib.delayed(_func)
Run Code Online (Sandbox Code Playgroud)

这并不理想,但它有效。