Search code examples
pythonpython-3.xprintingwritetofileconsole-output

Within contextlib.redirect_stdout() the print()-function causes an AttributeError: 'str' object has no attribute 'write'


I tried to redirect the entire console output of a specific part of my python code to a textfile following the advice of this post.

According to that post, it should work with contextlib.redirect_stdout(), but when the first print()-command appears within my custom function custom_function_with_internal_print_calls(), it throws the AttributeError: 'str' object has no attribute 'write'.

dummy_file = "dummy_textfile.txt"  # file to which the stdout shall be redirected

with contextlib.redirect_stdout(dummy_file):
    # Direct print()-function call
    print("Informative string which shall go to the textfile instead of the console.")

    # Indirect print()-function calls (internally)
    custom_function_with_internal_print_calls(**kwargs)

EDIT: In my particular case, instead of a print()-function within the with-environment, I have a custom function which has internal calls to Python's built-in print()-function. It shouldn't matter if the print()-function appears inside another function, or directly at the top-level to reproduce the error.

Options already tried: Other workarounds don't seem to provide the solution I'm looking for,such as

redefining the print()-function or

writing a decorator for python 2.7x (as I'm using python 3.7x), or also

redirecting the print()-function to a file object via print('Filename:', filename, file=f). The latter would mean in my case to pass a file-handler to all sub-functions in my enclosed function of choice, which is too much extra code modification for this special case.

I hope to be able to employ just the environment with contextlib.redirect_stdout(dummy_file): wrapped around my function in order to redirect every console output of this very function to the dummy_file.

The documentation of contextlib.redirect_stdout() doesn't help me either. Thanks in advance for suggestions.


Solution

  • I found the solution via passing a file-handler "f" to the function contextlib.redirect_stdout(f) instead of the filepath dummy_file, as suggested in this post.

    dummy_file = "dummy_textfile.txt"  # file to which the stdout shall be redirected
    
    with open(dummy_file, 'w') as f:
        with contextlib.redirect_stdout(f):
            # Indirect print()-function calls (internally)
            custom_function_with_internal_print_calls(**kwargs)
    

    With this, all print()-function calls write to the dummy_file and restores the standard console output afterwards.