This page discusses the benefits of replacing the current print statement with an equivalent builtin. The output function presented below does everything the print statement does without requiring any hacking of the grammar, and also makes a number of things significantly easier.
Benefits of using a function instead of a statement
- Extended call syntax provides better interaction with sequences
Keyword argument sep allows separator to be changed easily and obviously
Keyword argument term allows line terminator to be changed easily and obviously
Keyword argument stream allows easy and obvious redirection
- The builtin can be replaced for application wide customisation (e.g. per-thread logging)
- Interacts well with PEP 309's partial function application
Sample implementation
This is a Python 2.4 compatible sample implementation, which is why it uses the name output rather than print. Try not to get too hung up on names at this stage
1 def output(*args, **kwds):
2 """Functional replacement for the print statement
3
4 >>> output(1, 2, 3)
5 1 2 3
6 >>> output(1, 2, 3, sep='')
7 123
8 >>> output(1, 2, 3, sep=', ')
9 1, 2, 3
10 >>> output(1, 2, 3, term='Alternate line terminator')
11 1 2 3Alternate line terminator
12 >>> import sys
13 >>> output(1, 2, 3, stream=sys.stderr)
14 1 2 3
15 >>> output(*range(10))
16 0 1 2 3 4 5 6 7 8 9
17 >>> output(*(x*x for x in range(10)))
18 0 1 4 9 16 25 36 49 64 81
19 """
20 # Parse the keyword-only optional arguments
21 defaults = {
22 "sep": " ",
23 "term": "\n",
24 "stream": sys.stdout,
25 }
26 for name, default in defaults.items():
27 item = None
28 try:
29 item = kwds[name]
30 except KeyError:
31 pass
32 if item is None:
33 kwds[name] = default
34 sep, term, stream = kwds["sep"], kwds["term"], kwds["stream"]
35 # Perform the print operation without building the whole string
36 for arg in args[:1]:
37 stream.write(str(arg))
38 for arg in args[1:]:
39 stream.write(sep)
40 stream.write(str(arg))
41 stream.write(term)
Code comparisons
These are some comparisons of current print statements with the equivalent code using the builtin (again, don't get too hung up on names here).
Standard printing:
1 print 1, 2, 3
2 output(1, 2, 3)
Printing without any spaces:
1 print "%d%d%d" % (1, 2, 3)
2 output(1, 2, 3, sep='')
Print as comma separated list:
1 print "%d, %d%, d" % (1, 2, 3)
2 output(1, 2, 3, sep=', ')
Print without a trailing newline:
1 print 1, 2, 3,
2 output(1, 2, 3, term='')
Print to a different stream:
1 print >> sys.stderr, 1, 2, 3
2 output(1, 2, 3, stream=sys.stderr)
Print a simple sequence:
1 print " ".join(map(str, range(10)))
2 output(*range(10))
Print a generator expression:
1 print " ".join(str(x*x) for x in range(10))
2 output(*(x*x for x in range(10)))