我正在尝试将gnuplot的包装器从python2移植到python3。大多数错误很容易修复,但与项目的沟通似乎出乎意料。我已经在以下(丑陋的)片段中找出了问题。
cmd = ['gnuplot']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
p.stdin.write("set terminal dumb 80 40\n")
p.stdin.write("plot '-' w p ls 1, '-' w p ls 2, '-' w p ls 3 \n")
p.stdin.write("1 2 3\n")
p.stdin.write("2 3 4\n")
p.stdin.write("\ne\n")
p.stdin.write("e\n")
p.stdin.write("e\n")
while True:
print(p.stdout.read(1),end="")
此代码在python2中工作并生成并打印结果,但在python3中失败。首先它抱怨字节和字符串,所以我添加universal_newlines=True
。从那里我无法理解为什么它在stdout上没有输出任何内容并在stderr中打印出来:
line 4: warning: Skipping data file with no valid points
line 5: warning: Skipping data file with no valid points
显然问题出在编码或通信中,因为我发出的命令是相同的,但我不知道在哪里查看或如何调试它。
欢迎提出任何建议。
答案 0 :(得分:4)
Python 3在字节和字符串之间比Python 2有更强的区别。因此,您必须将要发送到标准输入的字符串编码为字节,并且必须将从标准输出接收的字节解码为字符串。另外,当我尝试你的程序时,我不得不像Charles建议的那样添加import subprocess
cmd = ['gnuplot']
p = subprocess.Popen(cmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
p.stdin.write("set terminal dumb 80 40\n".encode())
p.stdin.write("plot '-' w p ls 1, '-' w p ls 2, '-' w p ls 3\n".encode())
p.stdin.write("1 2 3\n".encode())
p.stdin.write("2 3 4\n".encode())
p.stdin.write("\ne\n".encode())
p.stdin.write("e\n".encode())
p.stdin.write("e\n".encode())
p.stdin.close()
print(p.stdout.read().decode())
print(p.stderr.read().decode())
,这样当gnuplot等待输入时程序就不会挂起。
这是我提出的代码的工作版本:
%x