繁体   English   中英

重定向sys.stdout时,Python PDB交互模式中断

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM