[Python-Dev] Replacement for print in Python 3.0
Nick Coghlan
ncoghlan at gmail.com
Sat Sep 3 03:02:43 CEST 2005
Steven Bethard wrote:
> Well, my proposal (which differs from Guidos) is that the print
> function (or whatever it ends up getting called) would have the
> semantics:
>
> def print(*args):
> sys.stdout.write(' '.join(str(arg) for arg in args))
> sys.stdout.write('\n')
I'd rather see a signature with the expressiveness of the current print
statement (full implementation below). I've called it 'output' rather than
'print' so that copy and pasting it into a 2.4 interactive session will work
(I also think the symmetry with input is cute).
With this function:
print 1, 2, 3 => output(1, 2, 3)
print >> sys.stderr, 1, 2, 3 => output(1, 2, 3, stream=sys.stderr)
print "%d%d%d" % (1, 2, 3) => output(1, 2, 3, sep='')
print 1, 2, 3, => output(1, 2, 3, end='')
Printing a tab-separated or comma separated list becomes trivial:
print "%d, %d, %d" % (1, 2, 3) => output(1, 2, 3, sep=', ')
print "%d\t%d\t%d" % (1, 2, 3) => output(1, 2, 3, sep='\t')
Printing the items in a sequence also becomes straightforward:
print " ".join(map(str, range(10))) => output(*range(10))
Playing well with generator expressions comes for free, too:
print " ".join(str(x*x) for x in range(10))
=> output(*(x*x for x in range(10)))
The capabilities of the current print statement reveal a lot of collective
wisdom regarding what is useful - the only real issues are that the syntax is
somewhat ugly and unique to the print statement, rather than using standard
function call syntax, and that as a result of the first issue, it is difficult
to control the behaviour of the separator.
Turning it into a proper function with three keyword arguments (sep, end,
stream) would allow both of these issues to be addressed, and also provide a
whole lot of fringe benefits relating to printing of sequences as described above.
Cheers,
Nick.
The sample implementation:
def output(*args, **kwds):
"""Functional replacement for the print statement
>>> output(1, 2, 3)
1 2 3
>>> output(1, 2, 3, sep='')
123
>>> output(1, 2, 3, sep=', ')
1, 2, 3
>>> output(1, 2, 3, end='Alternate line ending')
1 2 3Alternate line ending
>>> import sys
>>> output(1, 2, 3, stream=sys.stderr)
1 2 3
>>> output(*range(10))
0 1 2 3 4 5 6 7 8 9
>>> output(*(x*x for x in range(10)))
0 1 4 9 16 25 36 49 64 81
"""
# Parse the keyword-only optional arguments
defaults = {
"sep": " ",
"end": "\n",
"stream": sys.stdout,
}
for name, default in defaults.items():
item = None
try:
item = kwds[name]
except KeyError:
pass
if item is None:
kwds[name] = default
sep, end, stream = kwds["sep"], kwds["end"], kwds["stream"]
# Perform the print operation without building the whole string
for arg in args[:1]:
stream.write(str(arg))
for arg in args[1:]:
stream.write(sep)
stream.write(str(arg))
stream.write(end)
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
---------------------------------------------------------------
http://boredomandlaziness.blogspot.com
More information about the Python-Dev
mailing list