Aemyl
Aemyl

Reputation: 2194

How does print handle the comma exactly?

Originally I thought:

print "text",

would be pretty much the same as

sys.stdout.write("text" + " ")

but then I tried following:

print '(',
sys.stdout.write("text")
print ')'

expected output:

( text)

or

(text )  # if the space is added by the next print statement

what I got:

(text)  # no space at all

Can anyone explain this behavior? I'm just curious

Upvotes: 2

Views: 588

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1121654

Printing consists of converting items to strings, then writing them to a file object (which is sys.stdout by default). In Python 2, the print statement keeps a flag on the file object you write to, called the soft space flag. See the file.softspace attribute and the PyFile_SoftSpace() function in the Python C API.

This flag is used to track when to write a space. Printing is internally implemented as a series of PRINT_ opcodes, and those manage the flag:

  • printing an item (with PRINT_ITEM or PRINT_ITEM_TO) first checks the flag and will write a space if it is set, and after writing the item out will set the flag again
  • writing a newline is a separate opcode (PRINT_NEWLINE or PRINT_NEWLINE_TO), and the clears the flag without writing a space.

However, writing to the file object directly, as you did with sys.stdout.write(), clears that flag (before executing the write):

>>> import sys
>>> if True:
...     sys.stdout.softspace = 1
...     sys.stdout.write('{}\n'.format(sys.stdout.softspace))
...     sys.stdout.softspace
...
1
0

(I used an if block to prevent the interpreter loop from writing the prompt in between).

So this is what happens in your example:

  • ( is written to sys.stdout and sys.stdout.softspace is set.
  • sys.stdout.write('text') clears the flag again and writes out text
  • before writing ), PRINT_ITEM checks for the flag, finds it is not set, and writes ). The flag is set again.
  • A newline is written by PRINT_NEWLINE, clearing the flag again.

All this is a lot of work to keep track of a simple feature, and one of the reasons that Python 3 moved to a function for printing. See PEP 3105.

Upvotes: 3

Related Questions