Search code examples
python-3.xfunctionpython-multithreading

Passing tuple to a function


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?


Solution

  • 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'))