sys.stdout 作为默认函数参数

far*_*sil 3 python stdout default-value sys

假设我们有以下虚拟函数:

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')
Run Code Online (Sandbox Code Playgroud)

鉴于 Python 在定义时计算函数的默认参数,设置sys.stdout为默认参数是否安全,或者可能会产生意想不到的副作用?

Wil*_*sem 5

我想到的一个问题是,您有时想要重定向sys.stdout到文件(或管道、设备等)

例如,您的主程序可能如下所示:

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()
Run Code Online (Sandbox Code Playgroud)

如果您希望程序在您提到一个文件时记录到文件(例如python3 file.py logfile.log),这可能会很有用。现在,既然您设置了sys.stdout,那么您将不会注意到该修改writeline

因此我认为这样写更安全:

def writeline(text, stream = None):
    if stream is None:
        stream = sys.stdout
    stream.write(text + '\n')
Run Code Online (Sandbox Code Playgroud)

一般来说,将不可变对象设置为默认参数可能是个好建议(例如None, False,(1,)等)可能是个好建议。只有在极少数情况下,Python 才会特意使用不可变的(或可能更改引用的)。

但是,如果您确定不会重定向sys.stdout到文件、管道等,那么这是安全的。