Ascii Menu I/O redirection

S

Steven D'Aprano

class console(object):
"""
This spoofs a single file like object, using stdout & - in
(Minimalistic proof of concept implementation) """

def __init__(self):
self.read = sys.stdin.read
self.readline = sys.stdin.readline
self.write = sys.stdout.write
self.flush = sys.stdout.flush
self.closeout = sys.stdout.close # keep references to close
self.closein = sys.stdin.close

def close(self):
self.closein()
self.closeout()


I'm not sure that closing stdin and stout are a good idea. This could
have side-effects for other parts of your program, and will almost
certainly end badly if you're running in the interactive interpreter.

Other than that, what you've done seems reasonable, although since every
instance of console() has the same state, I'd write it slightly
differently:

class console(object):
"""
This spoofs a single file like object, using stdout & - in
(Minimalistic proof of concept implementation)
"""
read = sys.stdin.read
readline = sys.stdin.readline
write = sys.stdout.write
flush = sys.stdout.flush
closeout = sys.stdout.close
closein = sys.stdin.close
@classmethod
def close(cls):
cls.closein()
cls.closeout()



[...]
Questions are:

Is this a reasonable way of doing this kind of thing? Is there a
canonical or better way of doing it? Am I missing something?

It seems to me that you might have been better off to write your program
to take two files, an input and an output, instead of forcing both to go
to the same file.

if 'serial' in sys.argv: # for RS-232 i/o to terminal
infile = open('/dev/ttyS0','r+b')
outfile = infile
else: # console i/o
infile = sys.stdin
outfile = sys.stdout



Hope this helps.
 
H

Hendrik van Rooyen

I am writing a small application with a simple ascii based menu.

The menu is used to test individual functions, and to change some timings.
Otherwise the application just runs automatically, depending on command
line options.

I want to be able to redirect the menu.
The console, a serial port, or possibly a socket are target candidates.

Now a serial port and a socket are single files, so I need a "file"
that represents the console, to pass to the working functions.

Simply re-assigning for instance sys.stdin.write to point to
sys.stdout.write, and using sys.stdin as such a file does not work...

So I do the following:

<start code fragment>

class console(object):
"""
This spoofs a single file like object, using stdout & - in
(Minimalistic proof of concept implementation)
"""

def __init__(self):
self.read = sys.stdin.read
self.readline = sys.stdin.readline
self.write = sys.stdout.write
self.flush = sys.stdout.flush
self.closeout = sys.stdout.close # keep references to close
self.closein = sys.stdin.close

def close(self):
self.closein()
self.closeout()

# see if we must run, and how:

if __name__ == "__main__":

if 'serial' in sys.argv: # for RS-232 i/o to terminal
f = open('/dev/ttyS0','r+b')
else: # console i/o
f = console()

sys.stderr = f # redirect errors
sys.stdout = f # redirect printing
sys.stdin = f # redirect raw_input stuff

if 'menu' in sys.argv: # test and timing changes
menu_loop(menu_dict,f) # (menu_dict is dispatch dict)
else: # else just run the system
autorun(menu_dict,f)

<end code fragment>

The above just shows a choice between console and serial as an
example - adding a socket option would be trivial.

This all seems to work, but I am asking here before I take the
trouble to turn it into production code, as I don't think it
is exactly a new problem.

Questions are:

Is this a reasonable way of doing this kind of thing?
Is there a canonical or better way of doing it?
Am I missing something?

Using Linux only.

- Hendrik
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,200
Latest member
LaraHunley

Latest Threads

Top