203 votes

Pourquoi une chaîne de caractères entre parenthèses ne crée-t-elle pas un tuple contenant uniquement cette chaîne de caractères ?

J'ai un problème avec le threading de Python et l'envoi d'une chaîne de caractères 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. Elle appelle une fonction simple qui, pour l'instant, n'a pour seule tâche que d'imprimer "hello".

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 s'agit de la décomposer en chaque caractère et d'essayer de passer les arguments de cette manière. Cela fonctionne bien si j'appelle simplement la fonction normalement, mais j'aimerais vraiment la configurer comme un thread séparé.

409voto

Stephen Points 16714

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

Ajoutez un ',' supplémentaire :

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

Vous pouvez également utiliser des parenthèses pour dresser une liste :

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

Si vous le remarquez, d'après la trace de la pile : self.__target(*self.__args, **self.__kwargs)

En *self.__args transforme votre chaîne en une liste de caractères et les transmet à la fonction processLine fonction. Si vous lui transmettez une liste d'un seul élément, elle transmettra cet élément comme premier argument - dans votre cas, la chaîne de caractères.

16voto

themefield Points 393

J'espère apporter ici des précisions sur le contexte.

Premièrement, la signature du constructeur de la méthode of threading::Thread :

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

args est l'argument tuple pour l'invocation cible. La valeur par défaut est ().

Deuxièmement, A 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 faisant suivre une valeur d'un virgule (il ne suffit pas de mettre une seule valeur entre parenthèses).

En revanche, une chaîne de caractères est une séquence de caractères, comme par exemple 'abc'[1] == 'b' . Ainsi, si l'on envoie une chaîne de caractères à args même entre parenthèses (ce qui est tout de même un comble), 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 lance un TypeError de se plaindre.

1voto

HASEEB ALI Points 1
from threading import Thread
from time import sleep
def run(name):
    for x in range(10):
        print("helo "+name)
        sleep(1)
def run1():
    for x in range(10):
        print("hi")
        sleep(1)
T=Thread(target=run,args=("Ayla",))
T1=Thread(target=run1)
T.start()
sleep(0.2)
T1.start()
T.join()
T1.join()
print("Bye")

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X