0

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

2 Answers 2

4

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)
)
Sign up to request clarification or add additional context in comments.

Comments

1

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

1 Comment

Your answer is helpful. Thanks!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.