On 06/21/2012 02:03 PM, Rotwang wrote: > On 21/06/2012 18:07, Dave Angel wrote: >> On 06/21/2012 11:19 AM, Rotwang wrote: >>> Hi all, I'm using Python 2.7.2 on Windows 7 and a module I've written >>> is acting strangely. I can reproduce the behaviour in question with >>> the following: >>> >>> --- begin bugtest.py --- >>> >>> import threading, Tkinter, os, pickle >>> >>> class savethread(threading.Thread): >>> def __init__(self, value): >>> threading.Thread.__init__(self) >>> self.value = value >>> def run(self): >>> print 'Saving:', >>> with open(os.path.join(os.getcwd(), 'bugfile'), 'wb') as f: >>> pickle.dump(self.value, f) >>> print 'saved' >>> >>> class myclass(object): >>> def gui(self): >>> root = Tkinter.Tk() >>> root.grid() >>> def save(event): >>> savethread(self).start() >>> root.bind('s', save) >>> root.wait_window() >>> >>> m = myclass() >>> m.gui() >>> >>> --- end bugtest.py --- >>> >>> >>> Here's the problem: suppose I fire up Python and type >>> >>>>>> import bugtest >>> >>> and then click on the Tk window that spawns and press 's'. Then >>> 'Saving:' gets printed, and an empty file named 'bugfile' appears in >>> my current working directory. But nothing else happens until I close >>> the Tk window; as soon as I do so the file is written to and 'saved' >>> gets printed. If I subsequently type >>> >>>>>> bugtest.m.gui() >>> >>> and then click on the resulting window and press 's', then 'Saving: >>> saved' gets printed and the file is written to immediately, exactly as >>> I would expect. Similarly if I remove the call to m.gui from the >>> module and just call it myself after importing then it all works fine. >>> But it seems as if calling the gui within the module itself somehow >>> stops savethread(self).run from finishing its job while the gui is >>> still alive. >>> >>> Can anyone help? >>> >>> >> >> I did not study your code, as I'm not very familiar with tkinter. >> However, I think I know your problem: >> >> You do not want to try to start up threads from within a import. An >> import is special, and somehow blocks threading while it's running. > > That would explain it. > > >> Consequently, a module should not try to do anything too fancy from >> within its top-level code. Add in the traditional: >> >> def main(): >> m = myclass() >> m.gui() >> >> if __name__ == "__main__": >> main() >> >> and just run it from the command line, as python bugtest.py > > In fact, running the module directly from the command line makes it > work properly as-is.
But if you leave it as-is, then you can't run it from the interactive interpreter. > > Thanks for your post. > just for completeness, see link; http://docs.python.org/library/threading.html " ... an import should not have the side effect of spawning a new thread and then waiting for that thread in any way..." -- DaveA -- http://mail.python.org/mailman/listinfo/python-list