使用python schedule模块与共享作业队列并行执行作业时如何传递参数 [英] How to pass arguments when execute jobs in parallel with a shared job queue using python schedule module

查看:140
本文介绍了使用python schedule模块与共享作业队列并行执行作业时如何传递参数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我打算并行运行多个作业,并遵循了此处 使用作业队列,但当我尝试传递参数时,它执行一次并引发异常 '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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆