【问题标题】:Can I write to terminal and a given file with one command in Python?我可以用 Python 中的一个命令写入终端和给定文件吗?
【发布时间】:2011-07-15 05:42:15
【问题描述】:

我已经看到有关 Bash 的这个问题得到了回答,但找不到适用于 Python 的问题。抱歉,如果这是重复的话。

是否可以使用一个命令打印到终端和输出文件?我对使用print >>sys.stdout = WritableObject 很熟悉,但我想避免为要记录的每一行重复打印命令。

我使用的是 Python 2.6,以防万一需要这些知识。

更重要的是,我希望它使用 IDLE 的命令行在基于 Windows 的系统上运行。所以,本质上,我希望 python 脚本向 IDLE 的终端和给定的日志文件报告。

编辑:对于发现此问题并决定采用我选择的答案的任何人,如果您需要帮助理解上下文管理器(就像我所做的那样),我推荐 Doug Hellman 的本周 Python 模块澄清。 This one details the context library.装饰师求助see this Stack Overflow question's answers.

【问题讨论】:

标签: python windows python-2.6 python-idle


【解决方案1】:

替换sys.stdout

class PrintAndLog(object):
    def __init__(self, fileOrPath): # choose which makes more sense
        self._file = ...

    def write(s):
        sys.stdout.write(s)
        self._file.write(s)

    def close(self):
        self._file.close()
    # insert wrappers for .flush, .writelines

_old_stdout = sys.stdout
sys.stdout = PrintAndLog(f)
... # print and stuff
sys.stdout = _old_stdout

可以放入上下文管理器(这至少是我第三次在 SO 上看到类似的东西......):

from contextlib import contextmanager

@contextmanager
def replace_stdout(f):
    old_stdout = sys.stdout
    try:
        sys.stdout = PrintAndLog(f)
        yield
    finally:
        sys.stdout = old_stdout

【讨论】:

  • @Chinmay:对象的属性如何影响内置函数?我仍然会添加下划线,因为该文件确实应该是私有的。
  • @delnan 我从来没有听说过上下文管理器.... 会调查它,并使用这种方法。谢谢。另外,既然你以前看过这个请求,你能不能找到一个以前的化身的链接?如果我的搜索不够彻底,我想了解一下我错过了什么。
  • 这可以进一步概括为一个接收两个可写对象而不是将其限制为stdout的TeeStream。
  • 这是一个小问题,但你最好把sys.stdout = ... 放在try 里面而不是放在外面。这样,如果像 KeyboardInterrupt 这样的异步异常发生在赋值之后但在输入异常处理程序之前,它仍然会正确清理。
【解决方案2】:

为什么不直接写一个函数呢?

def myPrint(anOpenFileObject, message):
    print message
    anOpenFileObject.write(message)

【讨论】:

  • f 是可写对象,我假设?
  • @Nathanus:编辑澄清。
【解决方案3】:

如果您在 Unix 中:在程序开始时,您可以 mkfifo 命名管道,然后在 bg 中启动一个 cat 从它到终端的 tee 和所需的输出文件。然后在整个程序中,输出到命名管道的 fd。最后,在退出之前 rm 命名管道。

但老实说,我只会在 print 周围制作一个包装器,可以打印到两个目标。

【讨论】:

    猜你喜欢
    • 2012-05-09
    • 2014-10-13
    • 2019-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多