[英]Python PDB interactive mode breaks when redirecting sys.stdout
After replacing sys.stdout
with a Tee logger (to redirect output to a file), PDB no longer works properly. 用Tee记录器替换
sys.stdout
(以将输出重定向到文件)后,PDB不再正常工作。 For example, pressing the up arrow produces ^[[A
instead of the previous command. 例如,按向上箭头会产生
^[[A
而不是前一个命令。
The problem can be reproduced using this snippet: 可以使用以下代码段重现该问题:
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()
Is there any way to replace sys.stdout
without breaking PDB? 有什么办法可以在不破坏PDB的情况下替换
sys.stdout
?
(1) You cannot have interactivity on the tee'd output because it's a regular stream, and not a terminal. (1)您不能在发球区域的输出上具有交互性,因为它是常规流,而不是终端。 A terminal allows to do a ton of things: position the cursor, erase contents, read keys, echo keypresses to the screen, etc. A regular file on a disk can't do all these things, this is why
pdb
fails to do these things in interactive mode. 终端可以做很多事情:定位光标,擦除内容,读取键,在屏幕上回显按键等等。磁盘上的常规文件不能完成所有这些事情,这就是为什么
pdb
无法做到这些交互模式下的事物。 You can check that sys.stdout.isatty()
returns True
is you run a REPL. 您可以检查
sys.stdout.isatty()
是否在运行REPL时返回True
。
(2) You can of course change every print
function invocation in your code to write to stdout and to whatever file you want, because you can redefine print
. (2)当然,您可以更改代码中的每个
print
函数调用 ,以写入stdout 和所需的任何文件,因为您可以重新定义print
。 This works in Python 3, and in Python 2.7 if you from __future__ import print
. 如果您
from __future__ import print
,这在Python 3和Python 2.7中都from __future__ import print
。 Then you can do things like this: 然后,您可以执行以下操作:
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.
With print
statements , your situation is worse. 使用
print
语句 ,您的情况会更糟。 Use strace
on Linux or DTrace
on macOS to capture the writing to stdout (and elsewhere) and redirect it to a file when starting your process: 在Linux上使用
strace
或在macOS 上使用DTrace
来捕获对stdout(以及其他地方)的写入,并在启动进程时将其重定向到文件:
strace -e trace=write -o writes.txt python your-script.py
It will write to the file something like write(1, 'Hello world!')
. 它将类似
write(1, 'Hello world!')
文件。 You would need to parse it and reconstruct output to stdout (1) specifically to produce a real copy of the output. 您将需要对其进行解析并将输出重构为stdout(1),以专门生成输出的真实副本。
I suppose pdb
's interactive mode will work under this, too; 我想
pdb
的交互模式也可以在这种情况下工作。 at the very least, Python REPL works fine under strace. 至少,Python REPL在strace下可以正常工作。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.