Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/xpath/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用导入的装饰器包装app.task函数时出现芹菜键错误;仅带导入的错误_Python_Celery_Celery Task_Celeryd - Fatal编程技术网

Python 使用导入的装饰器包装app.task函数时出现芹菜键错误;仅带导入的错误

Python 使用导入的装饰器包装app.task函数时出现芹菜键错误;仅带导入的错误,python,celery,celery-task,celeryd,Python,Celery,Celery Task,Celeryd,鉴于布局: background \ tasks \ __init__.py generic.py helpers.py __init__.py _server.py config.py router.py server.py 并以芹菜为背景启动\u server.py。\u server worker 当我试图用延迟(…)调用通用.adder函数时,在Worker中给了我一个键错误:u'gene

鉴于布局:

background \
    tasks  \
        __init__.py
        generic.py
        helpers.py
    __init__.py
    _server.py
    config.py
    router.py
    server.py
并以芹菜为背景启动
\u server.py
。\u server worker

当我试图用
延迟(…)
调用
通用.adder
函数时,在Worker中给了我一个
键错误:u'generic.adder'

加法器功能:

文件
generic.py

from background.server import app
from background.tasks.helpers import standardized_task

@standardized_task(app, name='generic.adder')
def adder(x, y):
    return x + y
__author__ = 'Blake'

import types

JSON_TYPES = [
    dict, list, unicode, str, int, long, float, bool, types.NoneType
]

def standardized_task(app, *args, **kwargs):
    def wrapped_task(fn):
        def wrapped_fn(*fnargs, **fnkwargs):
            throws = fnkwargs.get('throws', Exception)
            raises = fnkwargs.get('raises', False)

            if not hasattr(throws, '__call__') and not isinstance(throws(), Exception):
                raise ValueError('throws value not of type Exception: %s' % type(throws))

            result, error = None, None

            try:
                result = fn(*fnargs, **fnkwargs)

                if type(result) not in JSON_TYPES:
                    result = unicode(result)

            except throws, e:
                error = e

                if raises:
                    raise
            finally:
                return {
                    'result': result,
                    'error': str(error) if error else None,
                    'meta': {
                        'args': fnargs, 'kwargs': fnkwargs
                    }
                }

        return app.task(wrapped_fn, *args, **kwargs)
    return wrapped_task
from background.server import app
from background.tasks.generic import *
…用一个函数包装,该函数接受
app
实例,并将芹菜任务的输入/输出标准化为JSON对象,该对象返回结果和函数。(包括在下面)然而,当这个包装器函数与generic.adder在同一个文件中时,问题是,它可以完美地工作——当它像上面那样导入和使用时,它抛出关键错误

我相信包装器以某种方式修改了传递给
app.task
name=..
属性,该属性使用
helpers.py
中的函数名,这导致从任务访问时找不到
generic.adder
的字面名称

还需要注意的是,如果您尝试从
\u server.py内部调用
加法器(..)
(该模块从芹菜CLI运行),那么它的工作原理是完美的;只有通过分布式接口调用时才会抛出错误;也就是说,进口产品独立于芹菜

文件
helpers.py

from background.server import app
from background.tasks.helpers import standardized_task

@standardized_task(app, name='generic.adder')
def adder(x, y):
    return x + y
__author__ = 'Blake'

import types

JSON_TYPES = [
    dict, list, unicode, str, int, long, float, bool, types.NoneType
]

def standardized_task(app, *args, **kwargs):
    def wrapped_task(fn):
        def wrapped_fn(*fnargs, **fnkwargs):
            throws = fnkwargs.get('throws', Exception)
            raises = fnkwargs.get('raises', False)

            if not hasattr(throws, '__call__') and not isinstance(throws(), Exception):
                raise ValueError('throws value not of type Exception: %s' % type(throws))

            result, error = None, None

            try:
                result = fn(*fnargs, **fnkwargs)

                if type(result) not in JSON_TYPES:
                    result = unicode(result)

            except throws, e:
                error = e

                if raises:
                    raise
            finally:
                return {
                    'result': result,
                    'error': str(error) if error else None,
                    'meta': {
                        'args': fnargs, 'kwargs': fnkwargs
                    }
                }

        return app.task(wrapped_fn, *args, **kwargs)
    return wrapped_task
from background.server import app
from background.tasks.generic import *
文件
\u server.py

from background.server import app
from background.tasks.helpers import standardized_task

@standardized_task(app, name='generic.adder')
def adder(x, y):
    return x + y
__author__ = 'Blake'

import types

JSON_TYPES = [
    dict, list, unicode, str, int, long, float, bool, types.NoneType
]

def standardized_task(app, *args, **kwargs):
    def wrapped_task(fn):
        def wrapped_fn(*fnargs, **fnkwargs):
            throws = fnkwargs.get('throws', Exception)
            raises = fnkwargs.get('raises', False)

            if not hasattr(throws, '__call__') and not isinstance(throws(), Exception):
                raise ValueError('throws value not of type Exception: %s' % type(throws))

            result, error = None, None

            try:
                result = fn(*fnargs, **fnkwargs)

                if type(result) not in JSON_TYPES:
                    result = unicode(result)

            except throws, e:
                error = e

                if raises:
                    raise
            finally:
                return {
                    'result': result,
                    'error': str(error) if error else None,
                    'meta': {
                        'args': fnargs, 'kwargs': fnkwargs
                    }
                }

        return app.task(wrapped_fn, *args, **kwargs)
    return wrapped_task
from background.server import app
from background.tasks.generic import *

答案不是使用装饰器,而是将芹菜.Task扩展到一个抽象类中,并使用,
@app.Task(name='…',base=MyNewAbstractTask)

下面的帖子对此进行了更好的解释: