[英]Python PDB interactive mode breaks when redirecting sys.stdout
用Tee记录器替换sys.stdout
(以将输出重定向到文件)后,PDB不再正常工作。 例如,按向上箭头会产生^[[A
而不是前一个命令。
可以使用以下代码段重现该问题:
import sys
import pdb
class Tee(object):
def __init__(self, name, mode):
self.file = open(name, mode)
self.stdout = sys.stdout
sys.stdout = self
def __del__(self):
sys.stdout = self.stdout
self.file.close()
def write(self, data):
self.file.write(data)
self.stdout.write(data)
def flush(self):
self.file.flush()
sys.stdout = Tee('test.txt', 'w')
pdb.set_trace()
有什么办法可以在不破坏PDB的情况下替换sys.stdout
?
(1)您不能在发球区域的输出上具有交互性,因为它是常规流,而不是终端。 终端可以做很多事情:定位光标,擦除内容,读取键,在屏幕上回显按键等等。磁盘上的常规文件不能完成所有这些事情,这就是为什么pdb
无法做到这些交互模式下的事物。 您可以检查sys.stdout.isatty()
是否在运行REPL时返回True
。
(2)当然,您可以更改代码中的每个print
函数调用 ,以写入stdout 和所需的任何文件,因为您可以重新定义print
。 如果您from __future__ import print
,这在Python 3和Python 2.7中都from __future__ import print
。 然后,您可以执行以下操作:
system_print = print # preserve the original.
def print_also_to(other_file):
def tee_print(*args, **kwargs):
system_print(*args, **kwargs) # Normally prints to stdout.
system_print(*args, **kwargs, file=other_file) # Write a copy.
return tee_print
print = print_also_to(open('/tmp/copy-of-stdout')) # A crude example.
print("Hello world!") # Unmodified code.
使用print
语句 ,您的情况会更糟。 在Linux上使用strace
或在macOS 上使用DTrace
来捕获对stdout(以及其他地方)的写入,并在启动进程时将其重定向到文件:
strace -e trace=write -o writes.txt python your-script.py
它将类似write(1, 'Hello world!')
文件。 您将需要对其进行解析并将输出重构为stdout(1),以专门生成输出的真实副本。
我想pdb
的交互模式也可以在这种情况下工作。 至少,Python REPL在strace下可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.