Python模块中写入临时文件后读取为空的原因排查
问题:Python中使用subprocess.Popen写入文件后读取结果为空
我正在编写一个处理当前目录文件的Python模块,代码如下:
import subprocess filename="tmp_file" # 将ls输出写入临时文件 with open(filename, 'w+') as f: subprocess.Popen(['ls', '-p'], stdout=f) f.seek(0) result = f.read()
但result为空,不过在Python解释器中逐行执行时可正常工作,请问原因是什么?
解答
这是因为subprocess.Popen()是非阻塞调用——当你执行这条语句时,Python会启动ls进程,但不会等待它完成就继续执行后面的f.seek(0)和result = f.read()了。这时候ls进程可能还没来得及把输出写入文件,你就读取了,自然得到空内容。
而在解释器中逐行执行时,你输入每一行后有时间间隔,足够ls进程完成并把输出写入文件,所以能正常读到结果。
解决这个问题有几种常用方法:
等待进程结束再读取
用Popen对象的wait()方法,确保进程执行完毕后再操作文件:import subprocess filename="tmp_file" with open(filename, 'w+') as f: proc = subprocess.Popen(['ls', '-p'], stdout=f) proc.wait() # 等待进程执行完成 f.seek(0) result = f.read()使用
communicate()方法(更推荐,无需临时文件)
如果不需要保存到临时文件,直接用communicate()获取输出,它会自动等待进程结束:import subprocess proc = subprocess.Popen(['ls', '-p'], stdout=subprocess.PIPE, text=True) result, _ = proc.communicate()使用更简洁的
subprocess.run()(Python 3.5+)run()是更上层的API,默认会等待进程完成,直接获取输出:import subprocess result = subprocess.run(['ls', '-p'], capture_output=True, text=True).stdout
内容的提问来源于stack exchange,提问作者Morpheusthewhite
相关产品推荐
相关产品推荐

