假设我们有以下虚函数:
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,还是可能有意外的副作用?
答案 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')
通常,将不可变对象设置为默认参数(如None
,False
,(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)