redirect standard output problem

Discussion in 'Python' started by iMath, Dec 21, 2012.

  1. iMath

    iMath Guest

    redirect standard output problem

    why the result only print A but leave out 888 ?

    import sys
    class RedirectStdoutTo:

    def __init__(self, out_new):
    self.out_new = out_new
    def __enter__(self):
    sys.stdout = self.out_new
    def __exit__(self, *args):
    sys.stdout = sys.__stdout__


    print('A')
    with open('out.log', mode='w', encoding='utf-8') as a_file, RedirectStdoutTo(a_file):

    print('B')
    print('C')

    print(888)
    iMath, Dec 21, 2012
    #1
    1. Advertising

  2. On Fri, Dec 21, 2012 at 4:23 PM, iMath <> wrote:
    > redirect standard output problem
    >
    > why the result only print A but leave out 888 ?


    No idea, because when I paste your code into the Python 3.3
    interpreter or save it to a file and run it, it does exactly what I
    would expect. A and 888 get sent to the screen, B and C go to the
    file.

    What environment are you working in? Python version, operating system,
    any little details that just might help us help you.

    ChrisA
    Chris Angelico, Dec 21, 2012
    #2
    1. Advertising

  3. iMath

    Hans Mulder Guest

    On 21/12/12 06:23:18, iMath wrote:
    > redirect standard output problem
    >
    > why the result only print A but leave out 888 ?
    >
    > import sys
    > class RedirectStdoutTo:
    >
    > def __init__(self, out_new):
    > self.out_new = out_new
    > def __enter__(self):
    > sys.stdout = self.out_new
    > def __exit__(self, *args):
    > sys.stdout = sys.__stdout__
    >
    >
    > print('A')
    > with open('out.log', mode='w', encoding='utf-8') as a_file, RedirectStdoutTo(a_file):
    >
    > print('B')
    > print('C')
    >
    > print(888)


    On my machine it works as you'd expect.

    If it doesn't work on your system, it might help to flush
    sys.stdout in a few strategic places:

    class RedirectStdoutTo:

    def __init__(self, out_new):
    self.out_new = out_new
    def __enter__(self):
    sys.stdout.flush()
    sys.stdout = self.out_new
    def __exit__(self, *args):
    sys.stdout.flush()
    sys.stdout = sys.__stdout__


    print('A')
    with open('out.log', mode='w', encoding='utf-8') as a_file,
    RedirectStdoutTo(a_file):

    print('B')
    print('C')

    print(888)
    sys.stdout.flush()


    Hope this helps,

    -- HansM
    Hans Mulder, Dec 21, 2012
    #3
  4. iMath

    Dave Angel Guest

    On 12/21/2012 12:23 AM, iMath wrote:
    > redirect standard output problem
    >
    > why the result only print A but leave out 888 ?
    >
    > import sys
    > class RedirectStdoutTo:
    >
    > def __init__(self, out_new):
    > self.out_new = out_new
    > def __enter__(self):
    > sys.stdout = self.out_new
    > def __exit__(self, *args):
    > sys.stdout = sys.__stdout__


    Just a comment. It'd be better to save and restore the stdout value,
    rather than restoring it to what it was at begin of process.

    Quoting from
    http://docs.python.org/3.3/library/sys.html?highlight=__stdout__#sys.__stdout__

    It can also be used to restore the actual files to known working file
    objects in case they have been overwritten with a broken object.
    However, the preferred way to do this is to explicitly save the previous
    stream before replacing it, and restore the saved object.


    My reasoning is that some function further up the stack may also be
    using a similar (or identical) redirection technique. Anyway, instead
    of using __stdout__, I'd use a saved value inside your object.

    def __init__(self, out_new):
    self.out_new = out_new
    def __enter__(self):
    self.savedstate = sys.stdout
    sys.stdout = self.out_new
    def __exit__(self, *args):
    sys.stdout = self.savedstate

    This may or may not solve your problem (I'd suspect that flush() is the
    right answer), but I still think it's worth doing.



    --

    DaveA
    Dave Angel, Dec 21, 2012
    #4
  5. iMath

    iMath Guest

    在 2012å¹´12月21日星期五UTC+8下åˆ3æ—¶24分10秒,Chris Angelico写é“:
    > On Fri, Dec 21, 2012 at 4:23 PM, iMath <> wrote:
    >
    > > redirect standard output problem

    >
    > >

    >
    > > why the result only print A but leave out 888 ?

    >
    >
    >
    > No idea, because when I paste your code into the Python 3.3
    >
    > interpreter or save it to a file and run it, it does exactly what I
    >
    > would expect. A and 888 get sent to the screen, B and C go to the
    >
    > file.
    >
    >
    >
    > What environment are you working in? Python version, operating system,
    >
    > any little details that just might help us help you.
    >
    >
    >
    > ChrisA



    on WinXP + python32

    when I run it through command line ,it works ok ,but when I run it through IDLE , only print A but leave out 888
    so why ?
    iMath, Dec 22, 2012
    #5
  6. iMath

    iMath Guest

    在 2012å¹´12月21日星期五UTC+8下åˆ3æ—¶24分10秒,Chris Angelico写é“:
    > On Fri, Dec 21, 2012 at 4:23 PM, iMath <> wrote:
    >
    > > redirect standard output problem

    >
    > >

    >
    > > why the result only print A but leave out 888 ?

    >
    >
    >
    > No idea, because when I paste your code into the Python 3.3
    >
    > interpreter or save it to a file and run it, it does exactly what I
    >
    > would expect. A and 888 get sent to the screen, B and C go to the
    >
    > file.
    >
    >
    >
    > What environment are you working in? Python version, operating system,
    >
    > any little details that just might help us help you.
    >
    >
    >
    > ChrisA



    on WinXP + python32

    when I run it through command line ,it works ok ,but when I run it through IDLE , only print A but leave out 888
    so why ?
    iMath, Dec 22, 2012
    #6
  7. On Sun, Dec 23, 2012 at 2:07 AM, iMath <> wrote:
    > when I run it through command line ,it works ok ,but when I run it through IDLE , only print A but leave out 888
    > so why ?


    Because IDLE has to fiddle with stdin/stdout a bit to function. Try
    adopting Dave's recommendation - you'll likely find that it then
    works.

    Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600
    32 bit (Intel)] on win32
    >>> sys.stdout is sys.__stdout__

    True

    The same in IDLE:
    >>> sys.stdout is sys.__stdout__

    False

    Whenever you work in IDLE, expect that some things will be slightly
    different, mostly to do with standard I/O streams. So when you post
    issues that you've come across, please state that you're using IDLE -
    it likely makes a difference!

    ChrisA
    Chris Angelico, Dec 22, 2012
    #7
  8. iMath

    Terry Reedy Guest

    On 12/22/2012 10:15 AM, Chris Angelico wrote:
    > On Sun, Dec 23, 2012 at 2:07 AM, iMath <> wrote:
    >> when I run it through command line ,it works ok ,but when I run it through IDLE , only print A but leave out 888
    >> so why ?

    >
    > Because IDLE has to fiddle with stdin/stdout a bit to function. Try
    > adopting Dave's recommendation - you'll likely find that it then
    > works.
    >
    > Python 3.3.0 (v3.3.0:bd8afb90ebf2, Sep 29 2012, 10:55:48) [MSC v.1600
    > 32 bit (Intel)] on win32
    >>>> sys.stdout is sys.__stdout__

    > True
    >
    > The same in IDLE:
    >>>> sys.stdout is sys.__stdout__

    > False


    In particular, on Windows,
    >>> import sys
    >>> sys.stdout

    <idlelib.run._RPCOutputFile object at 0x0000000002D852E8>
    >>> sys.__stdout__
    >>>


    In other words, sys.__stdout__ is None!

    To explain: IDLE runs in two processes connected by sockets. There is
    one process for user code and one for the gui. The user code process
    should be invisible as the gui process handles all user interaction. On
    Windows, this mean a process with no window and no input/output, which
    is what the pythonw (windowless) exe is for. (I believe IDLE on *nix
    uses an invisible window instead.) In any case, sys.stdout is set to a
    remote procedure call object that sends output to the socket connection.
    The gui process reads the socket and call the tkinter method to all text
    to a tk text box.

    > Whenever you work in IDLE, expect that some things will be slightly
    > different, mostly to do with standard I/O streams. So when you post
    > issues that you've come across, please state that you're using IDLE -
    > it likely makes a difference!


    Indeed! Especially for i/o issues, retest in the command window;-).

    --
    Terry Jan Reedy
    Terry Reedy, Dec 22, 2012
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. KC Wong
    Replies:
    0
    Views:
    383
    KC Wong
    Aug 19, 2003
  2. Roedy Green
    Replies:
    0
    Views:
    374
    Roedy Green
    Aug 19, 2003
  3. JimWilh
    Replies:
    6
    Views:
    2,706
    Andrew Thompson
    Jun 29, 2005
  4. Sal
    Replies:
    1
    Views:
    406
  5. Venks
    Replies:
    5
    Views:
    237
    Ken Bloom
    Dec 6, 2007
Loading...

Share This Page