Reputation: 2194
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
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:
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 againPRINT_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
)
, PRINT_ITEM
checks for the flag, finds it is not set, and writes )
. The flag is set again.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