Why Print Became a Function in Python 3
The transition of print from a statement in Python 2 to
a built-in function in Python 3 was introduced to provide greater
flexibility, improve syntactic consistency, and eliminate awkward
language edge cases. By transforming print into a
first-class function, Python enabled standard keyword arguments for
formatting and stream redirection, simplified the language's core
grammar, allowed print to be passed as an argument or
overridden, and resolved common syntax traps that frequently confused
developers.
Flexibility with Keyword Arguments
In Python 2, customizing output required ad-hoc syntax that was
unique to the print statement. Suppressing a trailing
newline required an unintuitive trailing comma
(print "text",), and redirecting output to an alternate
stream like sys.stderr required the obscure "chevron"
syntax (print >>sys.stderr, "text").
Making print() a function allowed these behaviors to be
handled using standard keyword arguments:
sep: Specifies the separator between objects (defaults to a space).end: Specifies what to append at the end (defaults to\n, replacing the trailing comma hack).file: Specifies the output stream (replacing the chevron syntax with standard arguments likefile=sys.stderr).flush: Allows explicit flushing of the output stream without needing to callsys.stdout.flush()separately.
Treating Print as a First-Class Object
In Python, statements cannot be passed around, but functions are
first-class objects. Converting print to a function meant
it could be treated like any other callable:
- It can be passed into higher-order functions, such as
map(print, my_list). - It can be stored in data structures, bound to new names, or passed as a callback to event handlers and threads.
- It can be easily mocked or monkey-patched for unit testing or custom
logging by reassigning
builtins.print.
Grammar Simplification and Eliminating Bugs
The print statement required a dedicated rule in
Python’s formal grammar, adding unnecessary complexity to the compiler.
Removing it streamlined the parser.
Additionally, the statement syntax caused subtle bugs, especially for
beginners or developers accustomed to other programming languages. In
Python 2, writing print("hello", "world") did not call a
function with two arguments; instead, it evaluated
("hello", "world") as a single tuple and printed its string
representation: ('hello', 'world'). In Python 3,
print("hello", "world") behaves naturally, printing the two
distinct strings separated by a space.