Python-Threading-String-Argumente

156

Ich habe ein Problem mit dem Python-Threading und dem Senden einer Zeichenfolge in den Argumenten.

def processLine(line) :
    print "hello";
    return;

.

dRecieved = connFile.readline();
processThread = threading.Thread(target=processLine, args=(dRecieved));
processThread.start();

Wobei dRecieved die Zeichenfolge einer Zeile ist, die von einer Verbindung gelesen wird. Es ruft eine einfache Funktion auf, die ab sofort nur noch einen Druckauftrag "Hallo" hat.

Ich erhalte jedoch den folgenden Fehler

Traceback (most recent call last):
File "C:\Python25\lib\threading.py", line 486, in __bootstrap_inner
self.run()
File "C:\Python25\lib\threading.py", line 446, in run
self.__target(*self.__args, **self.__kwargs)
TypeError: processLine() takes exactly 1 arguments (232 given)

232 ist die Länge der Zeichenfolge, die ich übergeben möchte. Ich denke, sie wird in jedes Zeichen aufgeteilt und versucht, die Argumente so zu übergeben. Es funktioniert gut, wenn ich die Funktion nur normal aufrufe, aber ich möchte sie wirklich als separaten Thread einrichten.

Anonym
quelle
49
Warum haben Sie am Ende jeder Zeile Semikolons?
Maikflow
@ Maikflow Ist das nicht eine gute Praxis? ASI konvertiert nicht semikolonierte Zeilen in semikolonierte Zeilen im Hintergrund afaik.
IK
@IK Siehe diese stackoverflow.com/questions/19365508/…
Maikflow

Antworten:

294

Sie versuchen, ein Tupel zu erstellen, aber Sie setzen nur eine Zeichenfolge in Klammern :)

Fügen Sie ein zusätzliches ',' hinzu:

dRecieved = connFile.readline()
processThread = threading.Thread(target=processLine, args=(dRecieved,))  # <- note extra ','
processThread.start()

Oder verwenden Sie Klammern, um eine Liste zu erstellen:

dRecieved = connFile.readline()
processThread = threading.Thread(target=processLine, args=[dRecieved])  # <- 1 element list
processThread.start()

Wenn Sie bemerken, aus dem Stack-Trace: self.__target(*self.__args, **self.__kwargs)

Das *self.__argsverwandelt Ihre Zeichenfolge in eine Liste von Zeichen, die an die processLine Funktion übergeben werden. Wenn Sie eine Liste mit einem Element übergeben, wird dieses Element als erstes Argument übergeben - in Ihrem Fall als Zeichenfolge.

Stephen
quelle
1
zusätzliche Klammern am Ende der zweiten Zeile des zweiten Codeblocks. Ich wollte es bearbeiten, aber es sind weniger als 6 Zeichen
Harmonickey
Wenn Sie arg2 mit dem Standardwert haben, tun Sie dies. threading.Thread(target=thread_function, args=(arg1,),kwargs={'arg2': arg2})
DeveScie
7

Ich hoffe, hier mehr Hintergrundwissen zu vermitteln.

Zunächst die Konstruktorsignatur der of-Methode threading :: Thread :

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)

args ist das Argument Tupel für das Ziel Aufruf. Der Standardwert ist ().

Zweitens eine Eigenart in Python über tuple:

Leere Tupel bestehen aus einem leeren Klammerpaar. Ein Tupel mit einem Element wird erstellt, indem einem Wert ein Komma folgt (es reicht nicht aus, einen einzelnen Wert in Klammern zu setzen).

Andererseits ist eine Zeichenfolge eine Folge von Zeichen wie 'abc'[1] == 'b'. Wenn Sie also eine Zeichenfolge an senden args, auch in Klammern (immer noch ein Stich), wird jedes Zeichen als einzelner Parameter behandelt.

Python ist jedoch so integriert und ähnelt nicht JavaScript, bei dem zusätzliche Argumente toleriert werden können. Stattdessen wirft es ein, sich TypeErrorzu beschweren.

Themenfeld
quelle