使用python schedule模块与共享作业队列并行执行作业时如何传递参数 [英] How to pass arguments when execute jobs in parallel with a shared job queue using python schedule module
问题描述
我打算并行运行多个作业,并遵循了此处 使用作业队列,但当我尝试传递参数时,它执行一次并引发异常 'NoneType' object is not callable
.代码如下:
I intended to run several jobs in parallel and followed the example here using a job queue, but it executed once and raised an exception 'NoneType' object is not callable
when I tried to pass arguments. The code listed below:
import Queue
import schedule
import threading
import time
def job(arg):
print 'Argument is %s' % arg
def worker_main():
while True:
try:
job_func = jobqueue.get()
job_func()
except Exception as e:
print e
jobqueue = Queue.Queue()
schedule.every(2).seconds.do(jobqueue.put, job(1))
schedule.every(2).seconds.do(jobqueue.put, job(2))
worker_thread = threading.Thread(target=worker_main)
worker_thread.start()
while True:
try:
schedule.run_pending()
time.sleep(1)
except Exception as e:
print e
sys.exit()
输出为:
Arg is 1
Arg is 2
'NoneType' object is not callable
'NoneType' object is not callable
'NoneType' object is not callable
'NoneType' object is not callable
'NoneType' object is not callable
'NoneType' object is not callable
...
有什么想法可以解决这个问题吗?
Any ideas to solve this?
推荐答案
原因是传递给 schedule.every(2).seconds.do() 中的
实际上是 do
方法的参数jobqueue.put, job(1))None
.
The reason for that is the parameter passed to do
method in schedule.every(2).seconds.do(jobqueue.put, job(1))
is actually None
.
因为代码正在调用 job
函数并将 1(和 2)作为参数传递给 job
.所以 job
函数的返回值(它是 None
因为它只是打印)作为第二个参数传递给 do
方法调用.因此,在作业队列中存储的是 None
实例,而不是函数引用.
Because the code is calling job
function and passing 1 (and 2) as arguments to job
. So the return value of the job
function (which is None
since it's just printing) is passed as the second argument to do
method call. So instead of a function reference, a None
instance is being stored in the job queue.
将参数传递给作业的问题是 schedule
包中的 do
方法可以接受额外的参数来运行作业,但是正在调度的是什么,就是将作业放入队列中,队列项只是函数引用,没有额外的参数.
The problem of passing arguments to the jobs is that the do
method from schedule
package, can accept extra arguments for the job to run, but what is being scheduled, is to put the job in the queue, and the queue items are only function references without extra arguments.
一种解决方案是将作业与其参数一起放入队列.然后工作人员需要获取它们并通过将参数传递给作业来调用作业.像这样:
One solution is to put the jobs alongside their arguments to the queue. Then the worker needs to get them and call the job by passing the arguments to it. Something like this:
import Queue
import schedule
import threading
import time
def job(arg):
print 'Argument is %s' % arg
def worker_main():
while True:
try:
job_func, job_args = jobqueue.get()
job_func(*job_args)
except Exception as e:
print e
jobqueue = Queue.Queue()
schedule.every(2).seconds.do(jobqueue.put, (job, [1]))
schedule.every(2).seconds.do(jobqueue.put, (job, [2]))
worker_thread = threading.Thread(target=worker_main)
worker_thread.start()
while True:
try:
schedule.run_pending()
time.sleep(1)
except Exception as e:
print e
sys.exit()
在这里,我们将作业函数引用的元组和参数列表放入队列.然后工作人员会获取它们,并将参数列表传递给作业函数.
Here we're putting a tuple of the job function reference, and a list of arguments to the queue. Then the worker would fetch them, and passes the list of arguments to the job function.
另一种解决方案是将作业(job(1)
和 job(2)
调用)包装在其他不需要参数的函数中,然后注册这些函数到作业队列,如下所示:
Another solution is to wrap the jobs (job(1)
and job(2)
calls) in other functions that do not need an argument, then register those functions to the job queue, like this:
def job1():
job(1)
def job2():
job(2)
jobqueue = Queue.Queue()
schedule.every(2).seconds.do(jobqueue.put, job1)
schedule.every(2).seconds.do(jobqueue.put, job2)
这篇关于使用python schedule模块与共享作业队列并行执行作业时如何传递参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!