Redirect stdout to a file in Python?

后端 未结 10 1340
轻奢々
轻奢々 2020-11-21 05:26

How do I redirect stdout to an arbitrary file in Python?

When a long-running Python script (e.g, web application) is started from within the ssh session and backgoun

相关标签:
10条回答
  • 2020-11-21 05:33

    Programs written in other languages (e.g. C) have to do special magic (called double-forking) expressly to detach from the terminal (and to prevent zombie processes). So, I think the best solution is to emulate them.

    A plus of re-executing your program is, you can choose redirections on the command-line, e.g. /usr/bin/python mycoolscript.py 2>&1 1>/dev/null

    See this post for more info: What is the reason for performing a double fork when creating a daemon?

    0 讨论(0)
  • 2020-11-21 05:37
    import sys
    sys.stdout = open('stdout.txt', 'w')
    
    0 讨论(0)
  • 2020-11-21 05:39

    Here is a variation of Yuda Prawira answer:

    • implement flush() and all the file attributes
    • write it as a contextmanager
    • capture stderr also

    .

    import contextlib, sys
    
    @contextlib.contextmanager
    def log_print(file):
        # capture all outputs to a log file while still printing it
        class Logger:
            def __init__(self, file):
                self.terminal = sys.stdout
                self.log = file
    
            def write(self, message):
                self.terminal.write(message)
                self.log.write(message)
    
            def __getattr__(self, attr):
                return getattr(self.terminal, attr)
    
        logger = Logger(file)
    
        _stdout = sys.stdout
        _stderr = sys.stderr
        sys.stdout = logger
        sys.stderr = logger
        try:
            yield logger.log
        finally:
            sys.stdout = _stdout
            sys.stderr = _stderr
    
    
    with log_print(open('mylogfile.log', 'w')):
        print('hello world')
        print('hello world on stderr', file=sys.stderr)
    
    # you can capture the output to a string with:
    # with log_print(io.StringIO()) as log:
    #   ....
    #   print('[captured output]', log.getvalue())
    
    0 讨论(0)
  • 2020-11-21 05:41

    you can try this too much better

    import sys
    
    class Logger(object):
        def __init__(self, filename="Default.log"):
            self.terminal = sys.stdout
            self.log = open(filename, "a")
    
        def write(self, message):
            self.terminal.write(message)
            self.log.write(message)
    
    sys.stdout = Logger("yourlogfilename.txt")
    print "Hello world !" # this is should be saved in yourlogfilename.txt
    
    0 讨论(0)
  • 2020-11-21 05:42

    If you want to do the redirection within the Python script, setting sys.stdout to a file object does the trick:

    import sys
    sys.stdout = open('file', 'w')
    print('test')
    

    A far more common method is to use shell redirection when executing (same on Windows and Linux):

    $ python foo.py > file
    
    0 讨论(0)
  • 2020-11-21 05:43

    Quoted from PEP 343 -- The "with" Statement (added import statement):

    Redirect stdout temporarily:

    import sys
    from contextlib import contextmanager
    @contextmanager
    def stdout_redirected(new_stdout):
        save_stdout = sys.stdout
        sys.stdout = new_stdout
        try:
            yield None
        finally:
            sys.stdout = save_stdout
    

    Used as follows:

    with open(filename, "w") as f:
        with stdout_redirected(f):
            print "Hello world"
    

    This isn't thread-safe, of course, but neither is doing this same dance manually. In single-threaded programs (for example in scripts) it is a popular way of doing things.

    0 讨论(0)
提交回复
热议问题