sys.stdout作为默认函数参数

时间:2017-03-13 11:08:32

标签: 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')

鉴于Python在定义时评估函数的默认参数,将sys.stdout设置为默认参数safe,还是可能有意外的副作用?

3 个答案:

答案 0 :(得分:3)

我想到的一个问题是,您有时想要将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()

如果您希望程序登录到文件,如果您提及(如python3 file.py logfile.log),则此功能非常有用。现在,由于您设置了sys.stdout,因此writeline方法不会记录该修改。

因此我认为写起来更安全:

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

通常,将不可变对象设置为默认参数(如NoneFalse(1,)等)可能是个不错的建议。只有在极少数情况下,才会在Python中故意使用不可变的(或可能更改引用的那些)。

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

答案 1 :(得分:1)

当对命名参数的常量值存有疑问时,最常使用的习惯用法是将参数设置为None,因此解析总是在运行时针对值进行在调用时是最新的:

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

答案 2 :(得分:0)

如果您正在使用Python 3的打印功能,如果file参数为None输出将照常打印到stdout。所以你可以像这样设置默认值None

def write_something(items, outfile=None):
    for item in items:
        print(item, file=outfile)