PEP 214, Extended Print Statement, owned by bwarsaw

This commit is contained in:
Barry Warsaw 2000-07-24 17:38:35 +00:00
parent e025e06bbe
commit 041efa077b
1 changed files with 153 additions and 0 deletions

153
pep-0214.txt Normal file
View File

@ -0,0 +1,153 @@
PEP: 214
Title: Extended Print Statement
Version: $Revision$
Owner: bwarsaw@beopen.com (Barry A. Warsaw)
Python-Version: 2.0
Status: Draft
Introduction
This PEP describes a syntax to extend the standard `print'
statement so that it can be used to print to any file-like object,
instead of the default sys.stdout. This PEP tracks the status and
ownership of this feature. It contains a description of the
feature and outlines changes necessary to support the feature.
This PEP summarizes discussions held in mailing list forums, and
provides URLs for further information, where appropriate. The CVS
revision history of this file contains the definitive historical
record.
Justification
`print' is a Python keyword and introduces the print statement as
described in section 6.6 of the language reference manual[1].
The print statement has a number of features:
- it auto-converts the items to strings
- it inserts spaces between items automatically
- it appends a newline unless the statement ends in a comma
The formatting that the print statement performs is limited; for
more control over the output, a combination of sys.stdout.write(),
and string interpolation can be used.
The print statement by definition outputs to sys.stdout. More
specifically, sys.stdout must be a file-like object with a write()
method, but it can be rebound to redirect output to files other
than specifically standard output. A typical idiom is
oldstdout = sys.stdout
sys.stdout = mylogfile
try:
print 'this message goes to my log file'
finally:
sys.stdout = oldstdout
The problem with this approach is that the binding is global, and
so affects every statement inside the try: clause. For example,
if we added a call to a function that actually did want to print
to stdout, this output too would get redirected to the logfile.
Proposal
This proposal introduces a syntax change to the print statement,
which allows the programmer to optionally specify the output file
target. An example usage is as follows:
print >> mylogfile, 'this message goes to my log file'
Formally, the syntax of the extended print statement is
print_stmt: "print" [">>" expr ","] [ expr ("," expr)* [","] ]
Where the the expression just after >> must yield an object with a
write() method (i.e. a file-like object). Thus these two
statements are equivalent:
print 'hello world'
print >> sys.stdout, 'hello world'
Reference Implementation
A reference implementation, in the form of a patch against the
Python 2.0 source tree, is available on SourceForge's patch
manager[2]. The approach this patch takes is to introduce two new
opcodes, one which temporarily rebinds sys.stdout to the specified
file object, performs the print as normal, and then bind
sys.stdout back to sys.__stdout__ (which is the real physical
standard out and should not be changed). In some ways this is
equivalent to the try/finally idiom above, except that the
rebinding of sys.stdout is in effect only for the duration of the
print statement itself.
An alternative approach is possible, where only one new opcode is
added. This opcode would be exactly like the existing PRINT_ITEM
opcode except that it would find the target file object at the top
of the stack, and use this file instead of digging it out of
sys.stdout.
Alternative Approaches
An alternative to this syntax change has been proposed (originally
by Moshe Zadka) which requires no syntax changes to Python. A
writeln() function could be provided (possibly as a builtin), that
would act much like extended print, with a few additional
features.
def writeln(*args, **kws):
import sys
file = sys.stdout
sep = ' '
end = '\n'
if kws.has_key('file'):
file = kws['file']
del kws['file']
if kws.has_key('nl'):
if not kws['nl']:
end = ' '
del kws['nl']
if kws.has_key('sep'):
sep = kws['sep']
del kws['sep']
if kws:
raise TypeError('unexpected keywords')
file.write(sep.join(map(str, args)) + end)
writeln() takes a three optional keyword arguments. In the
context of this proposal, the relevant argument is `file' which
can be set to a file-like object with a write() method. Thus
print >> mylogfile, 'this goes to my log file'
would be written as
writeln('this goes to my log file', file=mylogfile)
writeln() has the additional functionality that the keyword
argument `nl' is a flag specifying whether to append a newline or
not, and an argument `sep' which specifies the separator to output
in between each item.
References
[1] http://www.python.org/doc/current/ref/print.html
[2] http://sourceforge.net/patch/download.php?id=100970
Local Variables:
mode: indented-text
indent-tabs-mode: nil
End: