threads module question

Daley, Mark W mark.w.daley at intel.com
Wed Aug 23 11:14:56 EDT 2000


My apologies about the script, I was giving bits and pieces in an attempt to
give the general idea without bogging down in details.  At any rate, when I
change

	thread.start_new_thread(main.showvalues(), <What goes here?>)

to

	thread.start_new_thread(main.showvalues)

I get this traceback:

Exception in Tkinter callback
Traceback (innermost last):
  File "C:\Program Files\Python\Lib\lib-tk\Tkinter.py", line 764, in
__call__
    return apply(self.func, args)
  File "C:\Python\gui.py", line 47, in interact
    thread.start_new_thread(main.showvalues)
TypeError: function requires at least 2 arguments; 1 given

It looks to me like Tkinter rigidly requires 2 arguments for the apply
function.  Am I misreading the traceback?  If so, I'm hosed, but if I'm
right, how do I get around this?  (BTW, I tried using the threading module,
but had problems with that, too, and this seemed a little easier.  I've been
known to be wrong, however.)

TIA

- Mark



-----Original Message-----
From: Thomas Wouters [mailto:thomas at xs4all.net]
Sent: Wednesday, August 23, 2000 2:36 AM
To: Daley, Mark W
Cc: 'python-list at python.org'
Subject: Re: threads module question


On Tue, Aug 22, 2000 at 03:11:01PM -0700, Daley, Mark W wrote:

> I don't understand what the threads module is telling me when it says
'first
> arg must be callable'.  Can anyone direct me on the correct syntax for
using
> this module?  Here is my feeble attempt:


> import thread

> main = Main()
> thread.start_new_thread(main.showvalues(), <What goes here?>)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^
This, and your traceback:

>   File "C:\Python\gui.py", line 47, in interact
>     thread.start_new_thread(main, 'self')
> TypeError: first arg must be callable

don't add up. Are you sure you are giving us the right code and the right
traceback ? :)

In any case, the first argument to thread.start_new_thread should be a
function, *not* a functionCALL. So in your example, it should be:

thread.start_new_thread(main.showvalues, <What goes here?>)

Note the absense of the ()'s after showvalues. You want to pass a reference
to the function, not the result of the functioncall. That solves the 'first
arg must be callable' error. As for the other arguments, you have to pass
the arguments you want the new thread to call showvalues() with as a tuple.
If you don't pass any arguments, it's called without arguments. Note that if
this is a method, rather than a function, you do not need to pass 'self'
explicitly! 

An easy way to see what arguments you want to pass is simply by writing the
call you want the thread to make. If it's

    main.showvalues()

you pass nothing as arguments. You just call

    thread.start_new_thread(main.showvalues)

If you want it to call

    main.showvalues(x, y, z)

you have to pass a tuple consisting of '(x, y, z)' as arguments:

    thread.start_new_thread(main.showvalues, (x, y, z))

And if you want it to pass keyword values as well:

    main.showvalues(x, y, z, likespam=spam)

you have to pass those in a seperate dict:

    thread.start_new_thread(main.showvalues, (x, y, z), {'likespam': spam})

In other words, start_new_thread is exactly like the builtin apply()
function. See the doc-string for either function for more information.

Also, you are probably better off using the threading module, rather than
the thread module. It's a tad more convenient to work with, though it costs
you some flexibility (but not much, and you aren't likely to need it,
anyway.)

-- 
Thomas Wouters <thomas at xs4all.net>

Hi! I'm a .signature virus! copy me into your .signature file to help me
spread!





More information about the Python-list mailing list