Python Threading String Arguments

156

Tengo un problema con el subproceso de Python y el envío de una cadena en los argumentos.

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

.

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

Donde dRecieved es la cadena de una línea leída por una conexión. Llama a una función simple que en este momento solo tiene un trabajo de impresión "hola".

Sin embargo me sale el siguiente error

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 es la longitud de la cadena que estoy tratando de pasar, así que supongo que se divide en cada carácter e intenta pasar los argumentos de esa manera. Funciona bien si solo llamo a la función normalmente, pero realmente me gustaría configurarla como un hilo separado.

Anónimo
fuente
49
¿Por qué tienes punto y coma al final de cada línea?
Maikflow
@Maikflow ¿No es una buena práctica? ASI convierte las líneas no con punto y coma en punto y coma en el fondo afaik.
IK

Respuestas:

296

Estás tratando de crear una tupla, pero solo estás entre paréntesis de una cadena :)

Agregue un ',' extra:

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

O use corchetes para hacer una lista:

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

Si observa, desde el seguimiento de la pila: self.__target(*self.__args, **self.__kwargs)

El *self.__argsda vuelta a su cadena en una lista de caracteres, pasarlos a la processLine función. Si le pasa una lista de un elemento, pasará ese elemento como primer argumento, en su caso, la cadena.

Stephen
fuente
1
paréntesis adicionales al final de la línea dos del segundo bloque de código. Quería editarlo, pero tiene menos de 6 caracteres
harmonickey
Si tiene arg2 con valor predeterminado, haga esto. threading.Thread(target=thread_function, args=(arg1,),kwargs={'arg2': arg2})
DeveScie
8

Espero proporcionar más conocimientos básicos aquí.

Primero, la firma del constructor del método de subprocesamiento :: Subproceso :

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

args es la tupla de argumentopara la invocación de destino. Por defecto es ().

Segundo, un capricho en Python sobre tuple:

Las tuplas vacías se construyen con un par de paréntesis vacíos; una tupla con un elemento se construye siguiendo un valor con una coma (no es suficiente encerrar un solo valor entre paréntesis).

Por otro lado, una cadena es una secuencia de caracteres, como 'abc'[1] == 'b'. Entonces, si envía una cadena a args, incluso entre paréntesis (todavía una picadura), cada carácter será tratado como un solo parámetro.

Sin embargo, Python está tan integrado y no es como JavaScript, donde se pueden tolerar argumentos adicionales. En cambio, arroja un TypeErrorquejarse.

campo temático
fuente