2016-04-18 19 views
0

Ich beabsichtigte, mehrere Jobs parallel auszuführen und folgte dem Beispiel here mit einer Jobwarteschlange, aber es einmal ausgeführt und eine Ausnahme ausgelöst 'NoneType' object is not callable, wenn ich versucht, Argumente zu übergeben. Der Code im Folgenden aufgeführt:Wie übergeben Sie Argumente beim Ausführen von Jobs parallel mit einer freigegebenen Jobwarteschlange mit Python Schedule Modul

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() 

Die Ausgabe lautet:

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 
... 

Irgendwelche Ideen, diese zu lösen?

Antwort

3

Der Grund dafür ist der Parameter do Methode in schedule.every(2).seconds.do(jobqueue.put, job(1)) ist eigentlich None übergeben.

Da der Code job Funktion aufruft und 1 (und 2) als Argumente an job übergeben. Der Rückgabewert der job-Funktion (None seit dem Drucken) wird als zweites Argument an den Methodenaufruf do übergeben. Anstelle einer Funktionsreferenz wird also eine None Instanz in der Jobwarteschlange gespeichert.

Das Problem Argument der Stellen vorbei ist, dass die do Methode aus schedule Paket, zusätzliche Argumente akzeptieren kann für den Job an, aber was geplant wird, ist die Arbeit in der Warteschlange zu stellen, und die Warteschlange-Elemente sind nur Funktionsreferenzen ohne zusätzliche Argumente.

Eine Lösung besteht darin, die Jobs zusammen mit ihren Argumenten in die Warteschlange zu stellen. Dann muss der Arbeiter sie holen und den Job anrufen, indem er die Argumente an ihn weitergibt. Etwas wie folgt aus:

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() 

Hier haben wir ein Tupel der Job-Funktion Referenz setzen sind, und eine Liste von Argumenten in die Warteschlange. Dann würde der Worker sie abrufen und die Liste der Argumente an die Jobfunktion übergeben.

Eine andere Lösung ist es, die Arbeitsplätze (job(1) und job(2) Anrufe) in anderen Funktionen wickeln, die ein Argument nicht benötigen, dann diese Funktionen an die Auftragswarteschlange registrieren, wie folgt aus:

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) 
+0

Dies wird erhöhen ein ' job() benötigt genau 1 Argument (0 gegeben) 'Ausnahme, ich denke, das Argument wurde an' do'-Funktion übergeben, was ich brauche, wurde übergeben, um 'job' zu funktionieren –

+0

Wahr, ich habe die Funktion nicht bemerkt, die geplant wurde, ist nicht der Job, sondern bringt den Job in die Warteschlange. Ich habe die Antwort aktualisiert. – farzad

+0

Danke! Du hast das definitiv gelöst –