【问题标题】:Piping output in Python: multiple channels for data and messages?Python中的管道输出:数据和消息的多个通道?
【发布时间】:2013-01-07 19:49:57
【问题描述】:

我正在做一些 python 编程,我想将一个程序的输出“管道”到另一个程序。使用 sys.stdin 和 sys.stdout 很容易做到这一点。但是,我还希望能够将信息和警告消息打印到终端。是否有任何(简单)方法可以拥有多个通道,将消息打印到终端,但将数据发送到另一个程序?

【问题讨论】:

  • 这个管道发生在哪里?您的 python 脚本是直接调度其他 python 脚本,还是直接从终端将输出从一个命令传递到另一个命令?如果您直接在终端上进行管道传输,那么 Python 的选择相当有限,因为在这种情况下,众所周知的马已经离开了马厩。然后,您可以并且很可能应该考虑重构您的代码,以便 Python 负责而不是终端,然后您就可以更好地控制数据的去向以及数据如何从 Python 中到达那里。

标签: python command-line


【解决方案1】:

您可以将stderr 用于终端输出,将stdout 用于管道。

您可能会发现subprocess.Popen 很有用。它会生成另一个程序作为单独的进程,并允许您根据需要定义 stdinstdoutstderr 的文件描述符。

【讨论】:

  • +1。事实上,这是stderr 存在的主要原因之一。
【解决方案2】:

这几乎就是 logging 模块的用途。您可以将消息记录到您可以在代码中的任何位置任意创建和命名的记录器,然后通过将处理程序附加到记录器,将数据推送给您想要的任何消费者。

如果这对您不起作用,moooeeeep 的子流程建议可能是下一个探索的最佳途径。这是一种文明的方式来完成与覆盖 sys.stdout 相同的事情,这是只有野蛮人和体弱者才应该做的事情。

【讨论】:

  • 我看不出日志记录有什么帮助。问题是标准输出被重定向到另一个程序,所以如果你将日志消息打印到标准输出,那么它们也会被发送到那个程序。
  • 其实我测试过了,看来重定向stdout并不会影响日志输出。如果你写: logger = logging.getLogger() logger.setLevel(logging.DEBUG) ch = logging.StreamHandler() ch.setLevel(logging.DEBUG) formatter = logging.Formatter('[%(name)s] %( levelname)s : %(message)s') ch.setFormatter(formatter) logger.addHandler(ch) 然后 logging.info("blah") 将把 "blah" 打印到终端,而不是发送到任何重定向 stdout 的地方.
  • 这是因为 StreamHandler 默认推送到 stderr,而不是 stdout。
【解决方案3】:

正如其他人所说,将stdout 用于数据,stderr 用于用户交互。以下是在最近的 python 版本(即 3.x 和 2.6 或更高版本)中如何做到这一点:

import sys
print("data", file=sys.stdout)
print("more data") # sys.stdout is the default

print("user interaction", file=sys.stderr)

结果:

#!/usr/bin/env python
desktop➜  ~  ./tmp.py            
data
more data
user interaction
desktop➜  ~  ./tmp.py > /dev/null 
user interaction
desktop➜  ~  ./tmp.py 2&> /dev/null 
data
more data

【讨论】:

    【解决方案4】:

    老实说,当我想快速执行此操作时,我不会弄乱代码,我只是使用 tee。它是一个 *nix 实用程序,可以完成您所说的拆分管道以进行显示和管道的操作。您可以进一步限制使用 grep 显示的内容。非常适合调试使用管道的东西。如果这是您的生产系统的一部分,尽管除非您必须这样做,否则我可能不会使用管道传递信息。如果你这样做了,记录你的错误/警告和 tail -f 你的日志。

    我不知道真正的 Python 答案,但它可以完成工作。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-19
      • 2017-10-19
      • 2021-02-21
      • 1970-01-01
      • 2021-12-25
      • 1970-01-01
      • 2021-07-11
      相关资源
      最近更新 更多