Python线程字符串参数

问题:Python线程字符串参数

我在使用Python线程并在参数中发送字符串时遇到问题。

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

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

其中dRecieved是连接读取的一行的字符串。它调用了一个简单的函数,到目前为止,该函数仅具有打印“ hello”的一项工作。

但是我收到以下错误

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是我尝试传递的字符串的长度,因此我猜想它会将其分解成每个字符并尝试传递类似的参数。如果我只是正常调用该函数,它将很好用,但是我真的想将其设置为单独的线程。

I have a problem with Python threading and sending a string in the arguments.

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

.

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

Where dRecieved is the string of one line read by a connection. It calls a simple function which as of right now has only one job of printing “hello”.

However I get the following 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 is the length of the string that I am trying to pass, so I guess its breaking it up into each character and trying to pass the arguments like that. It works fine if I just call the function normally but I would really like to set it up as a separate thread.


回答 0

您正在尝试创建一个元组,但是您只是在用括号括起来:)

添加一个额外的’,’:

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

或使用方括号列出:

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

如果您注意到,从堆栈跟踪中: self.__target(*self.__args, **self.__kwargs)

*self.__args将您的字符串转换成字符的列表,将它们传递给processLine 函数。如果将一个元素列表传递给它,它将把该元素作为第一个参数传递-在您的情况下为字符串。

You’re trying to create a tuple, but you’re just parenthesizing a string :)

Add an extra ‘,’:

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

Or use brackets to make a list:

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

If you notice, from the stack trace: self.__target(*self.__args, **self.__kwargs)

The *self.__args turns your string into a list of characters, passing them to the processLine function. If you pass it a one element list, it will pass that element as the first argument – in your case, the string.


回答 1

我希望在这里提供更多背景知识。

首先,方法threading :: Thread的构造函数签名:

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

args是目标调用的参数元组。默认为()。

第二,关于Python 的怪癖tuple

空元组由一对空括号组成;一个带有一个项目的元组是通过在值后面加上逗号来构造的(将单个值括在括号中是不够的)。

另一方面,字符串是字符序列,例如'abc'[1] == 'b'。因此,如果将字符串发送到args,即使在括号中(仍然是一个字符串),每个字符也将被视为单个参数。

但是,Python是如此集成,并且不像JavaScript那样可以容忍额外的参数。相反,它引发了TypeError抱怨。

I hope to provide more background knowledge here.

First, constructor signature of the of method threading::Thread:

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

args is the argument tuple for the target invocation. Defaults to ().

Second, A quirk in Python about tuple:

Empty tuples are constructed by an empty pair of parentheses; a tuple with one item is constructed by following a value with a comma (it is not sufficient to enclose a single value in parentheses).

On the other hand, a string is a sequence of characters, like 'abc'[1] == 'b'. So if send a string to args, even in parentheses (still a sting), each character will be treated as a single parameter.

However, Python is so integrated and is not like JavaScript where extra arguments can be tolerated. Instead, it throws an TypeError to complain.