[Python-ideas] Replacing the standard IO streams (was Re: changing sys.stdout encoding)

MRAB python at mrabarnett.plus.com
Sat Jun 9 18:42:53 CEST 2012


On 09/06/2012 12:00, Paul Moore wrote:
> On 9 June 2012 10:55, Nick Coghlan<ncoghlan at gmail.com>  wrote:
>>  So, after much digging, it appears the *right* way to replace a
>>  standard stream in Python 3 after application start is to do the
>>  following:
>>
>>      sys.stdin = open(sys.stdin.fileno(), 'r',<new settings>)
>>      sys.stdout = open(sys.stdout.fileno(), 'w',<new settings>)
>>      sys.stderr = open(sys.stderr.fileno(), 'w',<new settings>)
>>
>>  Ditto for the other standard streams. It seems it already *is* as
>>  simple as with any other file, we just collectively forgot about:
>
> One minor point - if sys.stdout is redirected, *and* you have already
> written to sys.stdout, this resets the file pointer. With test.py as
>
> import sys
> print("Hello!")
> sys.stdout = open(sys.stdout.fileno(), 'w', encoding='utf-8')
> print("Hello!")
>
> test.py>a gives one line in a, not two (tested on Windows, Unix may
> be different). And changing to "a" doesn't resolve this...
>
> Of course, the actual use case is to change the encoding before
> anything is written - so maybe a small note saying "don't do this" is
> enough. But it's worth mentioning before we get the bug report saying
> "Python lost my data" :-)
>
I find that this:

print("Hello!")
sys.stdout = open(sys.stdout.fileno(), 'w', encoding='utf-8')
print("Hello!")

prints the string "Hello!\r\r\n", but this:

print("Hello!")
sys.stdout.flush()
sys.stdout = open(sys.stdout.fileno(), 'w', encoding='utf-8')
print("Hello!")

prints the string "Hello!\r\nHello!\r\r\n".

I had hoped that the flush would be enough, but apparently not.



More information about the Python-ideas mailing list