Jiechao Li
Jiechao Li

Reputation: 366

python passing tuple as function parameter

I know this question sounds stupid, but I just cannot get it right.

I want to start a new thread to execute this function with multiple arguments. I don't know how to get it done. There are always error here.

thread = threading.Thread(target=urllib2.urlopen, args=((url=REMOTE_SERVER_URL, data=context),))
thread.start()

The new thread would start this function.

urllib2.urlopen(url=REMOTE_SERVER_URL, data=context)

Can anyone help me? how to get it right? Thanks

Upvotes: 0

Views: 1647

Answers (2)

James Sapam
James Sapam

Reputation: 16930

Solution is already given above by @Blender.

But little bit of explanation for this class Thread constructor.

In threading module, Class Thread doesn't use any *args and **kwargs,

class threading.Thread(group=None, target=None, name=None, args=(), kwargs={})

In the above snippet args is just an argument which default value is an empty tuple, and kwargs is another argument which default value is empty dictionary. This is different from a function like def foo(*args, **kwargs) So, if you want to pass tuples argument please use args and if you want to pass dictionary argument please kwargs.

So, if you create an object like as below will run without any error, but which is wrong.

>>> thread = threading.Thread(target=urllib2.urlopen, args='some argument which is not tuple', kwargs='some argument which is not dict')
>>> 

From the source code: please check the args and kwargs line, there is no unpacking there.

def __init__(self, group=None, target=None, name=None,
             args=(), kwargs=None, verbose=None):
    assert group is None, "group argument must be None for now"
    _Verbose.__init__(self, verbose)
    if kwargs is None:
        kwargs = {}
    self.__target = target
    self.__name = str(name or _newname())
    self.__args = args
    self.__kwargs = kwargs
    self.__daemonic = self._set_daemon()
    self.__ident = None
    self.__started = Event()
    self.__stopped = False
    self.__block = Condition(Lock())
    self.__initialized = True
    # sys.stderr is not stored in the class like
    # sys.exc_info since it can be changed between instances
    self.__stderr = _sys.stderr

If you don't like this answer please, let me know in comment, I will remove it.

thanks

Upvotes: 1

Blender
Blender

Reputation: 298046

Tuples don't take keyword arguments, they're not functions. If you want to pass in keyword arguments, pass a dictionary as the kwargs argument:

thread = threading.Thread(target=urllib2.urlopen, kwargs={
    'url': REMOVE_SERVER_URL,
    'data': context
})

Or:

thread = threading.Thread(
    target=urllib2.urlopen,
    kwargs=dict(url=REMOVE_SERVER_URL, data=context)
)

Upvotes: 4

Related Questions