Use a context manager for python script output to a file?

前端 未结 1 379
孤独总比滥情好
孤独总比滥情好 2020-12-12 00:08

I\'m programming a script where I have an option, to be passed on the command line, whether the script should print its results to stdout or to a predefined results file. A

相关标签:
1条回答
  • 2020-12-12 00:38

    A context manager is something you can use with a with statement. It is explicitly designed to:

    • perform some setup,
    • give you an object, and
    • perform some teardown again (even if you raise an exception).

    For example, open can be used as a context manager. In the following code

    with open(...) as f:
        # do stuff
    

    it doesn't matter what stuff is, the file will always be closed. (Well, usually. Except in silly cases like the power being turned off or the process being killed.)

    You should use a context manager when you are in this sort of situation. It doesn't look to me like you are, so I see no reason for a context manager.


    There is an alternative (not better or worse, just different) way of writing your code that does use a context manager. If you want to redirect stdout temporarily -- but ensure that you restore it when you're done -- then you are in the situation above. Here's an example:

    @contextlib.contextmanager
    def redirect_stdout(stream):
        import sys
        sys.stdout = stream
        yield
        sys.stdout = sys.__stdout__
    

    You can then write code like

    with open(...) as f:
        with redirect_stdout(f):
            # do stuff
    

    and any writes to stdout in stuff will go to f instead.


    EDIT: You are correct that there is no way conditionally to have a context manager: either you are in one or you aren't. You could always write your own which might do nothing:

    @contextlib.contextmanager
    def maybe_open(path, do_nothing=True):
        if do_nothing:
            f = None
            yield sys.stdout
        else:
            f = open(path)
            yield f
    
        if f:
            f.close()
    

    This is almost certainly overkill.

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