In the following code:
def fun(args, **kwargs):
print(len(args))
thread = threading.Thread(
target=fun, args=('Cats', 'Dogs', 'Tigers'), kwargs={'sep': ' & '})
thread.start()
I am trying to pass a tuple to the parameter args
but it gives the following error:
TypeError: fun() takes 1 positional argument but 3 were given
But when I use args=(('Cats', 'Dogs', 'Tigers'),)
it works. I understand that it is considered as a tuple but why ('Cats', 'Dogs', 'Tigers')
is not being considered as a tuple?
In the first case you are passing a tuple as Thread
's args
parameter. In the second case you are passing a tuple containing a tuple as its first entry.
len(
('Cats', 'Dogs', 'Tigers')
) # 3
len(
(('Cats', 'Dogs', 'Tigers'))
) # 1
The args
parameter of threading.Thread
is splatted into target
's call (so each argument in the iterable passed to args
is unpacked into a separate argument for target
):
threading.Thread(target=fun, args=('Cats', 'Dogs', 'Tigers'))
# is equivalent to (but in another thread)
fun(*('Cats', 'Dogs', 'Tigers'))
# which is equivalent to
fun('Cats', 'Dogs', 'Tigers')
compared to:
threading.Thread(target=fun, args=(('Cats', 'Dogs', 'Tigers'),))
# is equivalent to (but in another thread)
fun(*(('Cats', 'Dogs', 'Tigers'),))
# which is equivalent to
fun(('Cats', 'Dogs', 'Tigers'))