[英]Python celery task canvas: SyntaxError: positional argument follows keyword argument
I have a chain of tasks that a celery worker runs. 我有一个芹菜工人要执行的任务。 When a task is finished the chain carries forward the result of that task to the next task as a (positional) argument.
任务完成后,链将该任务的结果作为(位置)参数转发给下一个任务。 Each task has it's own arguments + *args to handle the carried forward arguments.
每个任务都有自己的参数+ * args来处理结转的参数。 The problem is that I want to use keyword argument for the arguments of the task but those carried forward arguments are just positional arguments.
问题是我想将关键字参数用作任务的参数,但是那些结转参数只是位置参数。 The following code is just a simple example to show my problem without use of celery chains:
以下代码只是一个简单的示例,用于显示我的问题而不使用芹菜链:
def test_func(data1,*args):
print(data1, '\t', args)
def b():
return {'data2':'b'}
test_func(data1='a', b())
I know that this generates "SyntaxError: positional argument follows keyword argument" because the first argument is using the argument name whereas the second one doesn't. 我知道这会生成“ SyntaxError:位置参数紧跟关键字参数”,因为第一个参数使用的是参数名称,而第二个参数则没有。
If I know how to properly return the result of function b() then my problem will be solved. 如果我知道如何正确返回函数b()的结果,那么我的问题将得到解决。 That is, to return the result of b() in a way that b() is considered as a keyword argument when calling
也就是说,以调用时将b()视为关键字参数的方式返回b()的结果
test_func(data1='a', b())
UPDATE: It turned out celery chains carry over the results of each task to the first argument of the next task in the chain, not the last argument. 更新:事实证明芹菜链会将每个任务的结果转移到链中下一个任务的第一个参数,而不是最后一个参数。 This was my bad as I was new to celery chains.
这对我来说很不好,因为我刚接触芹菜连锁店。 Therefore, I just switched the place of positional and keyword arguments in the function's header and my problem was solved as bellow:
因此,我只是切换了位置和关键字参数在函数标题中的位置,而我的问题解决如下:
def test_func(data1, data2):
print(data1, '\t', data2)
def b():
return 'b'
test_func(b(),data2='a')
As Python allows to have a keyword argument after a positional argument, everything turned out to be smoothly running. 由于Python允许在位置参数之后使用关键字参数,因此所有内容都可以顺利运行。
Thanks to @MatiasCicero and @C.Nivs for their answers. 感谢@MatiasCicero和@ C.Nivs的回答。
Change your test_func
to: 将您的
test_func
更改为:
def test_func(**kwargs):
# kwargs is a dict containing the keyword arguments
print(*kwargs)
Then, you can just do: 然后,您可以执行以下操作:
test_func(data1='a', **b())
# Same as doing test_func(data1='a', data2='b')
Change your function call to: 将函数调用更改为:
test_func('a', b())
Positional args always come first in function definitions and calls 位置arg在函数定义和调用中始终排在第一位
In general, the order goes like so: 通常,顺序如下:
def myfunction(pos1, pos2, *args, **kwargs):
# do things
where pos1
and pos2
are positional args. 其中
pos1
和pos2
是位置args。 They have no default value. 它们没有默认值。
*args
is a list of non-keyword arguments, passed in like *args
是非关键字参数的列表,像
myfunction(pos1, pos2, [1, '2', 333])
**kwargs
is a dictionary of keyword arguments and they always go last: **kwargs
是关键字参数的字典,它们总是倒数第二位:
myfunction(pos1, pos2, [1, '2', 333], {'key':'val'})
EDIT: 编辑:
If you just get rid of the data1=
in your function call, you should be fine 如果您只是在函数调用中删除了
data1=
,那应该没问题
>>> test_func('a', b())
a ({'data2': 'b'},)
If you need it to be unpacked, then: 如果需要打开包装,请:
def test_func(data_1, **kwargs):
print(data_1, '\t', '\t'.join([kwargs[k] for k in kwargs.keys()]))
And you can unpack the results from b()
您可以从
b()
解压缩结果
>>> test_func('a', **b())
a b
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.