Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass List as an argument to a function in threading.Timer

Tags:

python

How to pass a list as an argument to function in threading.Timer(...) ? Please see the following code. I would like to pass nb[] as an argument

nb=['192.168.1.2', '192.168.1.3', '192.168.1.4']
ping_thread = threading.Timer(12.0, pingstarter, nb,)
ping_thread.start()

pingstarter is a funciton and taking argument as a list.

I am getting the following error. If it is required I can post all codes.

Thank you.

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 522, in __bootstrap_inner
    self.run()
  File "/System/Library/Frameworks/Python.framework/Versions/2.6/lib/python2.6/threading.py", line 726, in run
    self.function(*self.args, **self.kwargs)
TypeError: pingstarter() takes exactly 1 argument (3 given)
like image 262
Pujan Avatar asked Nov 18 '25 13:11

Pujan


2 Answers

The problem is simple: you need to pass the list argument nb to threading.Timer() as the single element of a sequence (I usually use a tuple, note the trailing comma inside the parentheses):

threading.Timer(12.0, pingstarter, (nb,))

...or, a list

threading.Timer(12.0, pingstarter, [nb])

Why? Well, threading.Timer() takes a sequence of arguments and a dict of keyword arguments. See the documentation on argument unpacking for more info.

Your list nb is being interpreted as the sequence of arguments, not as a single argument, so pingstarter eventually gets called with like:

pingstarter('192.168.1.2', '192.168.1.3', '192.168.1.4')

...instead of:

pingstarter(['192.168.1.2', '192.168.1.3', '192.168.1.4'])

Hence, you need to wrap it in another sequence.

like image 65
detly Avatar answered Nov 20 '25 03:11

detly


Try wrapping your pingstarter in another function:

def wrapper:
    nb = ['', '', '']
    pingstarter(nb)

ping_thread = threading.Timer(12.0, wrapper)

Alternatively, redefine pingstarter so it is expecting the arguments in the way they're being passed. Instead of something like:

def pingstarter(nb):

do something like:

def pingstarter(*nb):

What this does is takes all arguments to pingstarter and concatenates them into a tuple, which is the variable nb. This takes care of the problem that Timer is making the call pingstarter(*nb) instead of pingstarter(nb).

Finally, you could pass threading.Timer a list containing a single element, the list you want passed:

ping_thread = threading.Timer(12.0, pingstarter, [nb])

which requires no change to your other code.

like image 35
Aaron Dufour Avatar answered Nov 20 '25 03:11

Aaron Dufour



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!