sys.stdout.write in python3 adds 11 at end of string

It's NOT appended to the written string. 11 here is the return value of sys.stdout.write(), which is the number of characters written.

See write:

Write the string s to the stream and return the number of characters written.


It's similar to:

>>> def foo():
...     print('something', end='')
...     return 42
...
>>> foo()
something42

A More General Question

This is a great question, but I don't believe it to be the most general. The question, Python 3 interpreter prints length to standard input for every write, is easier to find if the string someone is trying to write happens to be a different length than 11. When I say "easier to find", I mean that it shows up more readily in a search. Also, the question I refer to includes a further question of "How do I fix this?"

The issue in both posts is an interpreter vs. script issue. Technically the Python shell (at least with the Python straight from python.org and default setup) uses a Read-eval-print loop (REPL), which you can read about in the previous link. More simply (and as stated by @Kieran in the answer to the other post I referred to)

[T]he python executable doesn't show returned values whereas the interpreter does.


How To Fix It

I think that's the shell vs. script issue has been well described in the question here. However, I want to address the question of "How to make it go away?" here. First of all, I think people that stumble on this question might wonder, especially if they use the interactive shell for development. Second of all, I can't answer this second, "How?" question with the other post being marked duplicate.

I'll repeat some of the code there with results, mostly because it's a bit quicker. As noted by @Yu_Hao , the documentation for write helps explain the behavior.

Write the string s to the stream and return the number of characters written.

The simple way to fix this is to assign the return value to a variable. (This is a good practice anyway, since it's good to know if a script called by another script completed successfully.) Here's a series of commands showing the problem, the reason, the solution, and a further use of the solution to make sure it worked.

(Windows) >python
(*NIX)    $ python3
Python 3.6.5 (v3.6.5:f59c0932b4, Mar 28 2018, 17:00:18) [<system-dependent-string>] on <system>
Type "help", "copyright", "credits" or "license" for more information.
>>> with open("garbage.file", "wb") as f:
...   for x in range(4):
...     f.write(b"xyz")
...
3
3
3
3
>>> with open("garbage.file", "wb") as f:
...   for x in range(4):
...     catch_ret_val = f.write(b"xyz")
...
>>> # Check it.
...
>>> with open("garbage.file", 'rb') as f:
...   f.read()
...
b'xyzxyzxyzxyz'
>>>
>>> # Note a snag if you want to use another way to check it.
...
>>> import os
(Windows) >>> os.system("type garbage.file")
xyzxyzxyzxyz0
(*NIX)    >>> os.system("cat garbage.file")
xyzxyzxyzxyz0
>>>
>>> # Oops, the return value of zero gets added on. 
...
>>> # We can use the same solution with the return value.
(Windows) >>> os_ret = os.system("type garbage.file")
xyzxyzxyzxyz>>>
(*NIX)    >>> os_ret = os.system("cat garbage.file")
xyzxyzxyzxyz>>>
>>>

Things still don't look quite nice. There's no carriage return and/or linefeed at the end of the file. If you want things a little cleaner...

(Windows) >>> os_ret = os.system("type garbage.file && echo(")
xyzxyzxyzxyz
(*NIX)    >>> os_ret = os.system("cat garbage.file && printf '\n'")
xyzxyzxyzxyz

Tags:

Python