[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

AltStyle によって変換されたページ (->オリジナル) /