2017-12-09 3 views
0

Mit der threading-Bibliothek versuche ich, eine Vielzahl von args/keyword args in die threading-Funktion zu übergeben. Es gibt drei verschiedene Situationen. Jede besteht aus einer vor der Threading-Funktion ausgeführten Funktion, die die Optionen an die Threading-Funktion übergibt, um ihr mitzuteilen, welche Funktion für das Threading aufgerufen werden soll, und die Argumente. In einigen Situationen gibt es in einigen Argumenten Schlüsselwortargumente und in einigen keine. Hier ist der Beispielcode der Threading-Funktion:Übergabe von * args oder ** kwargs an threading.Thread()

def create_some_threads(my_target, *my_args, **my_keyword_args): 
     for DeviceName in Devices: 
      device_ip = Devices[DeviceName]['mgmt_ip'] 
      my_thread = threading.Thread(target=my_target, args=(device_ip, DeviceName, *my_args, **my_keyword_args)) 
      my_thread.start() 

Leider bekomme ich den Fehler:

my_thread = threading.Thread(target=my_target, args=(device_ip, DeviceName, *args, **kwargs)) 
                       ^                
SyntaxError: invalid syntax 

Hier ist die Funktion, wo ich in den * my_args nennen:

pingable_devices = {} 
unpingable_devices = {} 
with open(os.devnull, "wb") as limbo: 
    print("\n[+] Progress:\n") 
    pbar = tqdm(total=100) 
    my_args = (pingable_devices, unpingable_devices, pbar, limbo) 
    my_target = ping_em_all 
    create_some_threads(my_target, *my_args) 

Das Problem ist, dass es für jede Funktion, die ich vor dem Aufruf der Threading-Funktion verwende, einen anderen Satz von Argumenten/Schlüsselwortargumenten gibt, die ich aufrufen werde. Ich habe versucht, dies zu einer eigenständigen Funktion zu machen, aber wenn ich es nicht so ausführen kann, muss ich vielleicht andere Wege gehen.

Edit: Dieses erste Problem wurde von unutbu gelöst, aber jetzt habe ich ein zweites Problem festgestellt. Es scheint, dass die Funktion, die von der Threading-Funktion aufgerufen wird, die Variablen nicht erkennt, die an Threading übergeben werden, my_args. Fehler ist unten:

Exception in thread Thread-4: 
Traceback (most recent call last): 
    File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner 
    self.run() 
    File "/usr/lib/python2.7/threading.py", line 754, in run 
    self.__target(*self.__args, **self.__kwargs) 
    File "Automatelab.py", line 157, in ping_em_all 
    ping_reply = subprocess.Popen(['ping', '-c', '2', '-w', '2', '-q', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait() 
NameError: global name 'device_ip' is not defined 

Hier kann die Funktion ping_em_all ist:

def ping_em_all(*my_args, **my_keyword_args): 
    """.rstrip is needed for the ip as .readline adds a \n to 
    the lines' text""" 
    if "Linux" in platform.system(): 
     ping_reply = subprocess.Popen(['ping', '-c', '2', '-w', '2', '-q', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait() 
    #Darwin is Mac OSX 
    elif "Darwin" in platform.system(): 
     ping_reply = subprocess.Popen(['ping', '-c', '2', '-t', '2', '-q', '-n', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait() 
     """Subprocess for Cygwin still not supported""" 
    else: 
    #Only other would be Windows 
     ping_reply = subprocess.Popen(['ping', '-n', '2', '-w', '2', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait() 

Antwort

1

Das Ziel ist called with:

self._target(*self._args, **self._kwargs) 

Daher könnten Sie verwenden:

def create_some_threads(my_target, *my_args, **my_keyword_args): 
    for DeviceName in Devices: 
     device_ip = Devices[DeviceName]['mgmt_ip'] 
     my_args = (device_ip, DeviceName,) + my_args 
     my_thread = threading.Thread(target=my_target, 
            args=my_args, kwargs=my_keyword_args)) 
     my_thread.start() 

Wenn Sie definieren, dass Sie eine Funktion mit *my_args oder **my_keyword_args in seiner Signatur definieren, beachten Sie, dass my_args ein Tupel innerhalb des Körpers dieser Funktion wird und my_keyword_args wird zu einem Diktat.

my_args = (device_ip, DeviceName,) + my_args 

einfach verkettet zwei weitere Werte auf der Vorderseite des my_args Tupels.


Die Fehlermeldung

NameError: global name 'device_ip' is not defined 

sagt, dass der Variablenname device_ip nicht in a scope that is accessible an dem Punkt definiert, wo die NameError aufgetreten.Ein Blick auf die ping_em_all Funktion zeigt, dass das wahr ist:

def ping_em_all(*my_args, **my_keyword_args): 
    """.rstrip is needed for the ip as .readline adds a \n to 
    the lines' text""" 
    if "Linux" in platform.system(): 
     ping_reply = subprocess.Popen(['ping', '-c', '2', '-w', '2', '-q', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait() 
    ...    

device_ip der erste Wert in my_args ist:

my_args = (device_ip, DeviceName,) + my_args 

Daher ping_em_all zu

def ping_em_all(*my_args, **my_keyword_args): 
    """.rstrip is needed for the ip as .readline adds a \n to 
    the lines' text""" 
    device_ip, DeviceName, my_args = my_args #<-- This defines device_ip 
    if "Linux" in platform.system(): 
     ping_reply = subprocess.Popen(['ping', '-c', '2', '-w', '2', '-q', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait() 
    ...    

Werte aus der auszupacken ändern my_args Tupel und geben Sie Variablennamen.

+0

Also das hat funktioniert, aber jetzt habe ich ein separates Problem. Alle Variablen in my_args werden von der Zielfunktion nicht erkannt. Siehe oben. – OfWolfAndMan

Verwandte Themen