Python, Tkinter and popen problem
Piet van Oostrum
piet at cs.uu.nl
Fri May 29 11:49:04 CEST 2009
>>>>> norseman <norseman at hughes.net> (n) wrote:
>n> I have tried both and Popen2.popen2().
>n> os.popen runs both way, contrary to docs.
What do you mean `os.popen runs both way'?
>n> # master.py
>n> import os
>n> # both lines work same
Of course, because 'r' is the default, and the bufsize for reading the
pipe only influences the performance.
>n> #xx= os.popen("/mnt/mass/py/z6.py").readlines()
>n> xx= os.popen("/mnt/mass/py/z6.py",'r',1).readlines()
>n> # I had hoped small buffer would force a sync (flush())
>n> # No such luck.
First, there is a difference between sync and flush. flush is writing
out any output that is buffered in the application program for that
file. Sync is writing out buffers (cache) in the operating system (to the
disc, network connection or similar). We are talking here about
flushing, not syncing. As we deal with a pipe, sync is not applicable.
Furthermore, whatever you do in the master program, such as setting the
buffer size has nothing to do with what happens in the child, so it will
not influence the flushing behaviour of the child. The only way to
influence that would be to use a pty instead of a pipe, because most
code uses a different buffering strategy for ttys and ptys compared to
files and pipes.
The next error in your program is that you use readlines()
This reads ALL input from your pipe before it proceeds. So essentially
it waits until the child process is finished and therefore gives you the
impression that it doesn't flush(). But it is not the child that is the
problem it is your master.
What you should do is take the pipe and do a readline()/print loop.
# popen is deprecated. Replace with subprocess:
from subprocess import Popen, PIPE
xx = Popen(["/mnt/mass/py/z6.py"], stdout=PIPE).stdout
line = xx.readline()
if not line: break
print "\t" + line,
for l in xx:
print "\t" + l,
doesn't work as the iterator for a file, including pipes, does a
read ahead (see the doc on file.next()) and therefore is not suitable for
>n> The direct question comes back to:
>n> How does one force a sync or flush() to take effect in Python with
>n> Tkinter in use? Or just in Python period. The keyword being force.
So it should be clear by now that the answer is to use flush().
And make sure you read AND process the flushed output in a proper way.
By the way, you have a nasty habit of using very unclear language to
pose your problems in this newsgroup/mailing list, instead of writing a
concise description and giving small examples of what code causes the
problem. This makes it extremely difficult to help you. I had to read
your messages at least 5 times to get an idea of what you were doing and
what the problem was that you wanted to solve.
Maybe you are dyslectic or something similar, in which case I apologize.
But anyway, I think you should learn to express yourself more clearly.
There are also courses for that.
Piet van Oostrum <piet at cs.uu.nl>
URL: http://pietvanoostrum.com [PGP 8DAE142BE17999C4]
Private email: piet at vanoostrum.org
More information about the Python-list