Arguments de chaîne de threads Python

156

J'ai un problème avec le threading Python et l'envoi d'une chaîne dans les arguments.

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

.

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

Où dRecieved est la chaîne d'une ligne lue par une connexion. Il appelle une fonction simple qui pour le moment n'a qu'un seul travail d'impression "bonjour".

Cependant, j'obtiens l'erreur suivante

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 est la longueur de la chaîne que j'essaie de passer, donc je suppose qu'il la divise en chaque caractère et essaie de passer les arguments comme ça. Cela fonctionne bien si j'appelle simplement la fonction normalement, mais j'aimerais vraiment la configurer en tant que thread séparé.

Anonyme
la source
49
Pourquoi avez-vous des points-virgules à la fin de chaque ligne?
Maikflow
@Maikflow N'est-ce pas une bonne pratique? ASI convertit les lignes non point-virgule en point-virgule en arrière-plan afaik.
IK

Réponses:

296

Vous essayez de créer un tuple, mais vous mettez simplement une chaîne entre parenthèses :)

Ajoutez un extra ',':

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

Ou utilisez des crochets pour faire une liste:

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

Si vous remarquez, à partir de la trace de la pile: self.__target(*self.__args, **self.__kwargs)

Le *self.__argstransforme votre chaîne en une liste de caractères, en les transmettant à la processLine fonction. Si vous lui passez une liste à un élément, il passera cet élément comme premier argument - dans votre cas, la chaîne.

Stephen
la source
1
des parenthèses supplémentaires à la fin de la deuxième ligne du deuxième bloc de code. Je voulais l'éditer mais il fait moins de 6 caractères
harmonickey
Si vous avez arg2 avec la valeur par défaut, procédez comme suit. threading.Thread(target=thread_function, args=(arg1,),kwargs={'arg2': arg2})
SpiralDev
8

J'espère fournir plus de connaissances de base ici.

Tout d'abord, la signature du constructeur de la méthode threading :: Thread :

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

args est le tuple d' argumentpour l'invocation de la cible. La valeur par défaut est ().

Deuxièmement, une bizarrerie en Python à propos de tuple:

Les tuples vides sont construits par une paire de parenthèses vides; un tuple avec un élément est construit en suivant une valeur avec une virgule (il ne suffit pas de mettre une seule valeur entre parenthèses).

D'autre part, une chaîne est une séquence de caractères, comme 'abc'[1] == 'b'. Donc, si vous envoyez une chaîne à args, même entre parenthèses (toujours une piqûre), chaque caractère sera traité comme un seul paramètre.

Cependant, Python est tellement intégré et n'est pas comme JavaScript où des arguments supplémentaires peuvent être tolérés. Au lieu de cela, il jette une TypeErrorplainte.

champ
la source