[英]Passing *args or **kwargs into threading.Thread()
Using the threading library, I am attempting to pass down a variety of args/keyword args into the threading function.使用线程库,我试图将各种参数/关键字参数传递到线程函数中。 There are three different situations.
存在三种不同的情况。 Each one consists of a function ran prior to the threading function, which passes down the options to the threading function to tell it what function to call for the threading, and the arguments.
每一个都包含一个在线程函数之前运行的函数,它将选项传递给线程函数以告诉它调用线程的哪个函数,以及参数。 In some situations, there will be keyword arguments, in some arguments, and in some, none.
在某些情况下,会有关键字参数,在某些参数中,而在某些情况下,没有。 Here is the sample code of the threading function:
下面是线程函数的示例代码:
def create_some_threads(my_target, *my_args, **my_keyword_args):
for DeviceName in Devices:
device_ip = Devices[DeviceName]['mgmt_ip']
my_thread = threading.Thread(target=my_target, args=(device_ip, DeviceName, *my_args, **my_keyword_args))
my_thread.start()
Unfortunately, I get the error:不幸的是,我收到错误:
my_thread = threading.Thread(target=my_target, args=(device_ip, DeviceName, *args, **kwargs))
^
SyntaxError: invalid syntax
Here is the function where I call in the *my_args:这是我在 *my_args 中调用的函数:
pingable_devices = {}
unpingable_devices = {}
with open(os.devnull, "wb") as limbo:
print("\n[+] Progress:\n")
pbar = tqdm(total=100)
my_args = (pingable_devices, unpingable_devices, pbar, limbo)
my_target = ping_em_all
create_some_threads(my_target, *my_args)
The problem is, for each function I use prior to calling the threading function, there are a different set of arguments/keyword arguments that I will call.问题是,对于我在调用线程函数之前使用的每个函数,我将调用一组不同的参数/关键字参数。 I attempted to make this a function on its own, but if I can't run it something like this, then I may have to explore other avenues.
我试图让它自己成为一个函数,但如果我不能像这样运行它,那么我可能不得不探索其他途径。
Edit: This first problem was solved by unutbu, but now I have encountered a second problem.编辑:第一个问题由 unutbu 解决,但现在我遇到了第二个问题。 It seems the function called by the threading function is not recognizing the variables passed into threading, my_args.
线程函数调用的函数似乎无法识别传递给线程函数 my_args 的变量。 Error is below:
错误如下:
Exception in thread Thread-4:
Traceback (most recent call last):
File "/usr/lib/python2.7/threading.py", line 801, in __bootstrap_inner
self.run()
File "/usr/lib/python2.7/threading.py", line 754, in run
self.__target(*self.__args, **self.__kwargs)
File "Automatelab.py", line 157, in ping_em_all
ping_reply = subprocess.Popen(['ping', '-c', '2', '-w', '2', '-q', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait()
NameError: global name 'device_ip' is not defined
Here is the ping_em_all function:这是 ping_em_all 函数:
def ping_em_all(*my_args, **my_keyword_args):
""".rstrip is needed for the ip as .readline adds a \n to
the lines' text"""
if "Linux" in platform.system():
ping_reply = subprocess.Popen(['ping', '-c', '2', '-w', '2', '-q', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait()
#Darwin is Mac OSX
elif "Darwin" in platform.system():
ping_reply = subprocess.Popen(['ping', '-c', '2', '-t', '2', '-q', '-n', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait()
"""Subprocess for Cygwin still not supported"""
else:
#Only other would be Windows
ping_reply = subprocess.Popen(['ping', '-n', '2', '-w', '2', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait()
The target is called with :目标被调用:
self._target(*self._args, **self._kwargs)
Therefore, you could use:因此,您可以使用:
def create_some_threads(my_target, *my_args, **my_keyword_args):
for DeviceName in Devices:
device_ip = Devices[DeviceName]['mgmt_ip']
my_args = (device_ip, DeviceName,) + my_args
my_thread = threading.Thread(target=my_target,
args=my_args, kwargs=my_keyword_args))
my_thread.start()
When you define you define a function with *my_args
or **my_keyword_args
in its call signature, note that my_args
becomes a tuple inside the body of that function, and my_keyword_args
becomes a dict.在定义函数时,在其调用签名中使用
*my_args
或**my_keyword_args
定义函数,请注意my_args
成为该函数体内的元组,而my_keyword_args
成为字典。
my_args = (device_ip, DeviceName,) + my_args
simply concatenates two more values to the front of the my_args
tuple.简单地将另外两个值连接到
my_args
元组的前面。
The error message错误信息
NameError: global name 'device_ip' is not defined
is saying that the variable name device_ip
has not been defined in a scope that is accessible at the point where the NameError
occurred.是说变量名称
device_ip
尚未在发生NameError
时可访问的范围内定义。 A look at the ping_em_all
function shows that that's true:查看
ping_em_all
函数表明这是真的:
def ping_em_all(*my_args, **my_keyword_args):
""".rstrip is needed for the ip as .readline adds a \n to
the lines' text"""
if "Linux" in platform.system():
ping_reply = subprocess.Popen(['ping', '-c', '2', '-w', '2', '-q', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait()
...
device_ip
is the first value in my_args
: device_ip
是my_args
的第一个值:
my_args = (device_ip, DeviceName,) + my_args
Therefore, change ping_em_all
to因此,将
ping_em_all
更改为
def ping_em_all(*my_args, **my_keyword_args):
""".rstrip is needed for the ip as .readline adds a \n to
the lines' text"""
device_ip, DeviceName, my_args = my_args #<-- This defines device_ip
if "Linux" in platform.system():
ping_reply = subprocess.Popen(['ping', '-c', '2', '-w', '2', '-q', device_ip.rstrip('\n')],stdout=limbo, stderr=limbo).wait()
...
to unpack values from the my_args
tuple and give them variable names.从
my_args
元组中解压值并给它们变量名。
There are a few possible issues I see.我看到了一些可能的问题。
In this line:在这一行:
my_thread = threading.Thread(target=my_target, args=(device_ip, DeviceName, *my_args, **my_keyword_args))
You don't need the asterisks in front of *my_args
and **my_keyword_args
The asterisk goes in the function parameters but inside of the function you can just refer to them as my_args
or my_keyword_args
.您不需要
*my_args
和**my_keyword_args
的星号 星号位于函数参数中,但在函数内部,您可以将它们称为my_args
或my_keyword_args
。 Secondly, for the args
parameter, you can remove the my_keyword_args
from that and instead put it at the end.其次,对于
args
参数,您可以从中删除my_keyword_args
并将其放在最后。 Here's a basic format to help clarify:这是帮助澄清的基本格式:
import threading
def start_thread(function_name, *args, **kwargs):
t = threading.Thread(target=function_name, args=args, kwargs=kwargs)
t.daemon = True
t.start()
def this_and_that(input_data, started=False, finished=False):
for i in names_list:
if started is True and finished is False:
print(i, started, finished)
elif started is True and finished is True:
print(i, started, finished)
else:
print(i, started, finished)
n = ['Steve','Smith']
start_thread(this_and_that, n, started=True, finished=True)
Output looks like this:输出如下所示:
Steve True True
Smith True True
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.