How to duplicate sys.stdout to a log file?

前端 未结 17 917
醉酒成梦
醉酒成梦 2020-11-22 06:54

Edit: Since it appears that there\'s either no solution, or I\'m doing something so non-standard that nobody knows - I\'ll revise my question to also ask: What is the best w

17条回答
  •  情话喂你
    2020-11-22 07:23

    As per a request by @user5359531 in the comments under @John T's answer, here's a copy of the referenced post to the revised version of the linked discussion in that answer:

    Issue of redirecting the stdout to both file and screen
    Gabriel Genellina gagsl-py2 at yahoo.com.ar
    Mon May 28 12:45:51 CEST 2007
    
        Previous message: Issue of redirecting the stdout to both file and screen
        Next message: Formal interfaces with Python
        Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
    
    En Mon, 28 May 2007 06:17:39 -0300, 人言落日是天涯,望极天涯不见家
     escribió:
    
    > I wanna print the log to both the screen and file, so I simulatered a
    > 'tee'
    >
    > class Tee(file):
    >
    >     def __init__(self, name, mode):
    >         file.__init__(self, name, mode)
    >         self.stdout = sys.stdout
    >         sys.stdout = self
    >
    >     def __del__(self):
    >         sys.stdout = self.stdout
    >         self.close()
    >
    >     def write(self, data):
    >         file.write(self, data)
    >         self.stdout.write(data)
    >
    > Tee('logfile', 'w')
    > print >>sys.stdout, 'abcdefg'
    >
    > I found that it only output to the file, nothing to screen. Why?
    > It seems the 'write' function was not called when I *print* something.
    
    You create a Tee instance and it is immediately garbage collected. I'd
    restore sys.stdout on Tee.close, not __del__ (you forgot to call the
    inherited __del__ method, btw).
    Mmm, doesn't work. I think there is an optimization somewhere: if it looks
    like a real file object, it uses the original file write method, not yours.
    The trick would be to use an object that does NOT inherit from file:
    
    import sys
    class TeeNoFile(object):
         def __init__(self, name, mode):
             self.file = open(name, mode)
             self.stdout = sys.stdout
             sys.stdout = self
         def close(self):
             if self.stdout is not None:
                 sys.stdout = self.stdout
                 self.stdout = None
             if self.file is not None:
                 self.file.close()
                 self.file = None
         def write(self, data):
             self.file.write(data)
             self.stdout.write(data)
         def flush(self):
             self.file.flush()
             self.stdout.flush()
         def __del__(self):
             self.close()
    
    tee=TeeNoFile('logfile', 'w')
    print 'abcdefg'
    print 'another line'
    tee.close()
    print 'screen only'
    del tee # should do nothing
    
    --
    Gabriel Genellina
    

提交回复
热议问题