10.8 Richer-Text I/O
The tools we have covered so far
support the minimal subset of text I/O functionality that all
platforms supply. Most platforms also offer richer-text I/O
capabilities, such as responding to single keypresses (not just to
entire lines of text) and showing text in any spot of the terminal
(not just sequentially).
Python extensions and core Python modules let you access
platform-specific functionality. Unfortunately, various platforms
expose this functionality in different ways. To develop
cross-platform Python programs with rich-text I/O functionality, you
may need to wrap different modules uniformly, importing
platform-specific modules conditionally (usually with the
try/except idiom covered in
Chapter 6).
10.8.1 The readline Module
The readline module
wraps the GNU Readline Library. Readline lets the user edit text
lines during interactive input, and also recall previous lines for
further editing and re-entry. GNU Readline is widely installed on
Unix-like platforms, and is available at http://cnswww.cns.cwru.edu/~chet/readline/rltop.html.
A Windows port (http://starship.python.net/crew/kernr/) is
available, but not widely deployed. Chris
Gonnerman's module, Alternative Readline for
Windows, implements a subset of Python's standard
readline module (using a small dedicated
.pyd file instead of GNU Readline) and can be
freely downloaded from http://newcenturycomputers.net/projects/readline.html.
When either readline module is loaded, Python uses
Readline for all line-oriented input, such as
raw_input. The interactive Python interpreter
always tries loading readline to enable line
editing and recall for interactive sessions. You can call functions
supplied by module readline to control advanced
functionality, particularly the history functionality for recalling
lines entered in previous sessions, and the completion functionality
for context-sensitive completion of the word being entered. See
http://cnswww.cns.cwru.edu/~chet/readline/rltop.html#Documentation
for GNU Readline documentation, with details on configuration
commands. Alternative Readline also supports history, but the
completion-related functions it supplies are dummy ones: these
functions don't perform any operation, and exist
only for compatibility with GNU Readline.
Returns the number of lines of history that are saved to the history
file. When the returned value is less than 0, all
lines in the history are saved.
parse_and_bind(readline_cmd)
|
|
Gives Readline a configuration command. To let the user hit Tab to
request completion, call parse_and_bind('tab:
complete'). See the GNU Readline documentation for
other useful values of readline_cmd.
read_history_file(filename='~/.history')
|
|
Loads history lines from the text file whose name or path is
filename.
read_init_file(filename=None)
|
|
Makes Readline load a text file, where each line is a configuration
command. When filename is
None, Readline loads the same file as last time.
Sets the completion function. When f is
None, Readline disables completion. Otherwise,
when the user enters a partial word start
and then hits Tab, Readline calls
f(start,i),
where i is an int,
initially 0. f returns
the ith possible word that begins with
start, or None when
there are no more. Readline calls f
repeatedly, with i set to
0, 1, 2,
..., until f returns
None.
Sets the number of lines of history that are saved to the history
file. When x is less than
0, all lines in the history are saved.
write_history_file(filename='~/.history')
|
|
Saves history lines to the text file whose name or path is
filename.
An example of a completion
function is in module rlcompleter. In an
interactive interpreter session (or, more practically, in the startup
file that the interpreter runs at the start of each interactive
session, as covered in Chapter 3), you can enter:
import readline, rlcompleter
readline.parse_and_bind('tab: complete')
Now, for the rest of this interactive session, you can hit Tab during
line editing and get completion for global names and object
attributes.
10.8.2 Console I/O
Terminals today are most often text windows
on a graphical screen. You may also use a true terminal or the
console (main screen) of a personal computer in text mode. All kinds
of terminals in use today support advanced text I/O functionality,
but you access this functionality in platform-dependent ways. The
curses package works only on Unix-like platforms
(there are persistent rumors of Windows ports of it, but
I've never found a working one). Modules
msvcrt, WConio, and
Console work only on Windows.
10.8.2.1 The curses package
The traditional Unix approach to
advanced terminal I/O is named curses, for
obscure historical reasons. The Python package
curses affords reasonably simple use, but still
lets you exert detailed if control required. I cover a small subset
of curses, enough to let you write programs with
rich text I/O functionality. See also Eric Raymond's
tutorial Curses Programming with Python, available at
http://py-howto.sourceforge.net/curses/curses.html,
for more information. Whenever I mention the screen in this section,
I mean the screen of the terminal (for example, the text window of a
terminal-emulator program).
The simplest and most effective way to use curses
is through the curses.wrapper module, which
supplies a single function.
Performs curses initialization, calls
func(stdscr,*args),
performs curses finalization (setting the terminal
back to normal behavior), and finally returns
func's result. The first
argument that wrapper passes to
func is stdscr, an
object of type curses.Window that represents the
whole terminal screen. wrapper ensures that the
terminal is set back to normal behavior, whether
func terminates normally or by propagating
an exception.
func should be a function that performs
all the tasks in your program that may need curses
functionality. In other words, func
normally contains (or more commonly calls, directly or indirectly,
functions containing) all of your program's
functionality, save perhaps for some non-interactive initialization
and/or finalization tasks.
curses models text and background colors of
characters as character attributes. Colors available on the terminal
are numbered from 0 to
curses.COLORS. Function
color_content takes a color number
n as its argument, and returns a tuple
(r,g,b)
of integers between 0 and 1000
giving the amount of each primary color in
n. Function color_pair
takes a color number n as its argument,
and returns an attribute code that you can pass to various methods of
a curses.Window object in order to display text in
that color.
curses lets you create multiple instances of type
curses.Window, each corresponding to a rectangle
on the screen. You can also create exotic variants, such as instances
of Panel, which are polymorphic with
Window but not tied to a fixed screen rectangle.
You do not need such advanced functionality in simple
curses programs: just use the
Window object stdscr that
curses.wrapper gives you. Call
w.refresh( ) to ensure
that changes made to any Window instance
w, including stdscr,
show up on screen. curses can buffer the changes
until you call refresh. An instance
w of Window supplies,
among many others, the following frequently used
methods.
w.addstr([y,x,]str[,attr])
|
|
Puts the characters in string
str, with attribute
attr, on w at
the given coordinates
(x,y),
overwriting any previous contents. All curses
functions and methods accept coordinate arguments in reverse order,
with y (the row number) before
x (the column number). If you omit
y,x,
addstr uses
w's current cursor
coordinates. If you omit attr,
addstr uses
w's current default
attribute. In any case, addstr, when done adding
the string, sets w's
current cursor coordinates to the end of the string it has added.
w.clrtobot( )
w.clrtoeol( )
|
|
clrtoeol writes blanks from
w's current cursor
coordinates to the end of the line. clrtobot, in
addition, also blanks all lines lower down on the screen.
Deletes one character from w at the given
coordinates
(x,y).
If you omit the
y,x
arguments, delch uses
w's current cursor
coordinates. In any case, delch does not change
w's current cursor
coordinates. All the following characters in line
y, if any, shift left by one.
Deletes from w the entire line at
w's current cursor
coordinates, and scrolls up by one line all lines lower down on the
screen.
Writes spaces to the entire terminal screen.
Returns an integer c corresponding to a
user keystroke. c between
0 and 255 represents an
ordinary character, while c greater than
255 represents a special key.
curses supplies names for special keys, so you can
test c for equality with such readable
constants as curses.KEY_HOME (the Home special
key), curses.KEY_LEFT (the left-arrow special
key), and so on. The list of all curses
special-key names (about 100 of them) is in Python's
free documentation, specifically, in the Python
Library Reference, Section
6.13.3 Constants, for
current versions of Python. If you have set window
w to no-delay mode by calling
w.nodelay(True),
w.getch raises an
exception if no keystroke is ready. By default, however,
w.getch waits until the
user hits a key.
Returns w's current
cursor coordinates as a tuple
(y,x).
w.insstr([y,x,]str[,attr])
|
|
Inserts the characters in string str, with
attribute attr, on
w at the given coordinates
(x,y),
shifting the rest of line rightwards. Any characters that shift
beyond the end of line are dropped. If you omit
y,x,
insstr uses
w's current cursor
coordinates. If you omit attr,
insstr uses
w's current default
attribute. In any case, when done inserting the string,
insstr sets
w's current cursor
coordinates to the first character of the string it has inserted.
Moves w's cursor to the
given coordinates
(x,y).
Sets w to no-delay mode when
flag is true, resets
w back to normal mode when
flag is false. No-delay mode affects
method w.getch.
Updates window w on-screen with all
changes the program has effected on w.
The curses.textpad module supplies the
Textpad class, which lets you support advanced
input.
Creates and returns an instance t of class
Textpad that wraps the curses
window instance window. Instance
t has one frequently used method:
- t.edit( )
-
Lets the user perform interactive editing on the contents of the
window instance that t wraps. The editing
session supports simple Emacs-like key bindings: normal characters
overwrite the window's previous contents, arrow keys
move the cursor, Ctrl-H deletes the character to the
cursor's left. When the user hits Ctrl-G, the
editing session ends, and edit returns the
window's contents as a single string, with newlines
as line separators.
10.8.2.2 The msvcrt module
The msvcrt module,
available only on Windows, supplies functions that let Python
programs access a few proprietary extras supplied by the Microsoft
Visual C++'s runtime library
msvcrt.dll. Some msvcrt
functions let you read user input character by character, rather than
reading a full line at a time.
Reads and returns one character from keyboard input, waiting if no
character is yet available for reading. getche
also echoes the character to screen (if printable), while
getch doesn't. When the user
presses a special key (arrows, function keys, etc.),
it's seen as two characters: first a
chr(0) or chr(224), then a
second character that, together with the first one, defines what
special key the user pressed. Here's how to find out
what getch returns for any key:
import msvcrt
print "press z to exit, or any other key to see code"
while 1:
c = msvcrt.getch( )
if c = = 'z': break
print "%d (%r)" % (c, c)
Returns True when a character is available for
reading (getch, if called, would return
immediately), otherwise False
(getch, if called, would wait).
Ungets character c: the next call to
getch or getche returns
c. It's an error to call
ungetch twice without intervening calls to
getch or getche.
10.8.2.3 The WConio and Console modules
Two Windows-specific extension modules
supply single-character keyboard input (like
msvcrt) and the ability to paint characters in
specified positions of the text screen. Chris
Gonnerman's Windows Console I/O module is small,
simple, and easy to use. Module WConio can be
freely downloaded from http://newcenturycomputers.net/projects/wconio.html.
Fredrik Lundh's Console module is very complete and
functionally rich. Module Console can be freely
downloaded from http://www.effbot.org/efflib/console/.
|