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

后端 未结 2 1375
走了就别回头了
走了就别回头了 2021-01-02 23:43

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         


        
相关标签:
2条回答
  • 2021-01-03 00:06

    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
    
    0 讨论(0)
  • 2021-01-03 00:13

    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
    
    0 讨论(0)
提交回复
热议问题