python:将sys.stdout打印更改为自定义打印功能

时间:2013-02-20 17:45:06

标签: python operator-overloading stdout

我试图了解如何创建自定义打印功能。 (使用python 2.7)

import sys
class CustomPrint():
    def __init__(self):
        self.old_stdout=sys.stdout #save stdout

    def write(self, text):
        sys.stdout = self.old_stdout #restore normal stdout and print
        print 'custom Print--->' + text
        sys.stdout= self # make stdout use CustomPrint on next 'print'
                         # this is the line that trigers the problem
                         # how to avoid this??


myPrint = CustomPrint()
sys.stdout = myPrint
print 'why you make 2 lines??...'

上面的代码将其打印到控制台:

>>> 
custom Print--->why you make 2 lines??...
custom Print--->

>>> 

我想只打印一行:

>>>    
1custom Print--->why you make 2 lines??...
>>>

但是无法弄清楚如何使这个自定义打印工作,我明白有某种递归触发第二个输出到控制台(我使用self.write,将stdout分配给self.write自己!)

我该怎么做才能做到这一点?或者我的方法完全错了......

3 个答案:

答案 0 :(得分:4)

一种解决方案可能是使用上下文管理器(如果已本地化)。

#!/usr/bin/env python
from contextlib import contextmanager
################################################################################
@contextmanager
def no_stdout():
    import sys
    old_stdout = sys.stdout
    class CustomPrint():
        def __init__(self, stdout):
            self.old_stdout = stdout

        def write(self, text):
            if len(text.rstrip()):
                self.old_stdout.write('custom Print--->'+ text)

    sys.stdout = CustomPrint(old_stdout)

    try:
        yield
    finally:
        sys.stdout = old_stdout
################################################################################
print "BEFORE"
with no_stdout():
    print "WHY HELLO!\n"
    print "DING DONG!\n"

print "AFTER"

以上产生:

BEFORE
custom Print--->WHY HELLO!
custom Print--->DING DONG!
AFTER

代码需要整理esp。关于班级应该做什么WRT设置stdout回到原来的样子。

答案 1 :(得分:2)

这不是递归。您的write函数会被调用两次,一次是您期望的文本,第二次是'\n'。试试这个:

import sys
class CustomPrint():
    def __init__(self):
        self.old_stdout=sys.stdout

    def write(self, text):
        text = text.rstrip()
        if len(text) == 0: return
        self.old_stdout.write('custom Print--->' + text + '\n')

我在上面的代码中做的是将新行字符添加到第一次调用中传递的文本中,并确保print语句的第二次调用,即打印新行的那个,不打印任何东西。

现在尝试注释掉前两行,看看会发生什么:

    def write(self, text):
        #text = text.rstrip()
        #if len(text) == 0: return
        self.old_stdout.write('custom Print--->' + text + '\n')

答案 2 :(得分:1)

如何做from __future__ import print_function。这样您将使用Python3打印函数而不是Python2的print语句。然后您可以重新定义打印功能:

def print(*args, **kwargs):
    __builtins__.print("Custom--->", *args, **kwargs)

但是有一个问题,你必须开始使用打印功能。