Suppose we have the following dummy function:
import sys
def writeline(text, stream=sys.stdout):
    stream.write(text + '\n')
with open('/path/to/file', 'w') as f:
    # writes to /path/to/file
    writeline('foo', f)
# writes to standard output
writeline('bar')
Given that Python evaluates default arguments for functions at definition time, is setting sys.stdout as default argument safe, or may it have unintended side effects?
A problem I think of, is that you sometimes want to redirect sys.stdout to a file (or pipe, device, etc.) yourself.
For instance your main program could look like:
if __name__ == '__main__':
    if len(sys.argv) > 1:
        sys.stdout = open(sys.argv[1],'w')
    try:
        # ... run the program
    finally:
        if len(sys.argv) > 1:
            sys.stdout.close()
This could be useful if you want your program to log to a file if you mention one (like python3 file.py logfile.log). Now since you set the sys.stdout, that modification will not be noted by your writeline method.
Therefore I think it is more safe to write:
def writeline(text, stream = None):
    if stream is None:
        stream = sys.stdout
    stream.write(text + '\n')
In general it is probably good advice to set immutable objects as default parameters (like None, False, (1,), etc.). Only in rare circumstances immutable ones (or ones that might change reference) are used on purpose in Python.
If you are however sure that you will not redirect sys.stdout to a file, pipe, etc. It is safe.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With