farsil farsil - 22 days ago 5
Python Question

sys.stdout as default function argument

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?

Answer Source

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.