将参数传递给threading.Thread

6
我正在Windows平台上使用Python 3。我使用threading.Thread动态运行函数,并且可能会带或不带参数进行调用。我正在设置一个包含多个项的列表,其中第一项是定义路径的字符串。其他参数将是列表中后面的项。因此,args可能等于['C:\SomePath'],也可能等于['C:\SomePath', 'First Argument', 'Second Argument']。我的调用看起来像这样:
my_script = threading.Thread(target=scr_runner, args=q_data.data)
my_script.start()

问题在于在调用 threading.Thread 和/或 start 函数的过程中,参数正在失去其列表特征(isinstance(q_data.data, str)=False),但在接受 script_to_run_data 参数的 scr_runner 函数内部,isinstance(script_to_run_data, str)=True.
我需要这个参数一直保持为列表。如何做到这点?
我在文档中读到 threading.Thread 函数期望一个元组作为参数。将类似 ['C:\SomePath'] 这样的内容转换为元组时,会出现某些问题,导致结果变成了字符串吗?
提前感谢您的时间!
以下是 MWE:
# coding=utf-8
""" This code tests conversion to list in dynamic calling. """

import threading


def scr_runner(script_to_run_data: tuple) -> None:
    """ This is the function to call dynamically. """
    is_list = not isinstance(script_to_run_data, str)
    print("scr_runner arguments are a list: T/F. " + str(is_list))


my_list=['C:\SomePath']
is_list = not isinstance(my_list, str)
print("About to run script with list argument: T/F. " + str(is_list))
my_script = threading.Thread(target=scr_runner, args=my_list)
my_script.start()

现在奇怪的是,当我使my_list具有更多的元素时,我会收到一个错误:

# coding=utf-8
""" This code tests conversion to list in dynamic calling. """

import threading


def scr_runner(script_to_run_data: tuple) -> None:
    """ This is the function to call dynamically. """
    is_list = not isinstance(script_to_run_data, str)
    print("scr_runner arguments are a list: T/F. " + str(is_list))


my_list=['C:\SomePath', 'First Argument', 'Second Argument']
is_list = not isinstance(my_list, str)
print("About to run script with list argument: T/F. " + str(is_list))
my_script = threading.Thread(target=scr_runner, args=my_list)
my_script.start()

产生错误:

About to run script with list argument: T/F. True
Exception in thread Thread-1:
Traceback (most recent call last):
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 916, in  
       _bootstrap_inner
    self.run()
  File "C:\ProgramData\Anaconda3\lib\threading.py", line 864, in run
    self._target(*self._args, **self._kwargs)
TypeError: scr_runner() takes 1 positional argument but 3 were given

1
上传一个带有函数定义的可工作代码。 - mehdix
@Mehdi Sadeghi:你懂了!感谢您查看我的问题。 - Adrian Keister
可能有一个解决方案:将 args=my_list 更改为 args=[my_list],尽管我认为这种行为有点违反直觉。 - Adrian Keister
@AdrianKeister:反直觉?如果args没有被隐式解包为target的参数,你如何期望将两个或更多参数传递给线程? - ShadowRanger
@ShadowRanger:是的,那是个好观点。谢谢! - Adrian Keister
1个回答

9
args是要传递的参数序列;如果您想将一个list作为唯一的位置参数传递,那么需要传递args=(my_list,)来使其成为包含list的单元素元组(或者等效地,args=[my_list])。
即使只传递一个参数,它也需要是一个参数序列,以避免您创建的歧义。如果scr_runner需要三个参数,其中两个具有默认值,并且my_list的长度为3,您是要将这三个元素作为三个参数传递,还是my_list应该是第一个参数,而其他两个参数保持默认值?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接