Can someone explain why sys.stdout.write()
appends 11
to my string?
$ python3
Python 3.4.3+ (default, Jul 28 2015, 13:17:50)
[GCC 4.9.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> x = 'hello'
>>> y = 'world'
>>> msg = ''
>>> import sys
>>> msg += x
>>> msg += '\n' + y
>>> msg
'hello\nworld'
>>> sys.stdout.write(msg)
hello
world11
>>> print(msg)
hello
world
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
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With