7

カスタム印刷関数を作成する方法を理解しようとしています。(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--->

>>> 

そして私は1行だけを印刷したい:

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

しかし、このカスタム印刷を機能させる方法がわかりません。コンソールへの2番目の出力をトリガーするある種の再帰があることを理解しています(self.writeを使用して、stdoutをself.write自身に割り当てます!)

どうすればこれを機能させることができますか?または私のアプローチは完全に間違っています...

4

3 に答える 3

5

再帰ではありません。何が起こるかというと、write関数が2回呼び出されます。1回目は期待するテキストで、2回目は。だけで呼び出されます'\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')

    def flush(self):
        self.old_stdout.flush()

上記のコードで行うことは、最初の呼び出しで渡されたテキストに改行文字を追加し、新しい行を印刷するためのprintステートメントによって行われた2番目の呼び出しが何も印刷しないことを確認することです。

次に、最初の2行をコメントアウトして、何が起こるかを確認してください。

    def write(self, text):
        #text = text.rstrip()
        #if len(text) == 0: return
        self.old_stdout.write('custom Print--->' + text + '\n')
于 2013-02-20T18:00:13.253 に答える
4

ローカライズされている場合、1つの解決策はコンテキストマネージャーを使用することです。

#!/usr/bin/env python
from __future__ import print_function

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を元の状態に戻します。

于 2013-02-20T18:12:54.097 に答える
1

やってみませんかfrom __future__ import print_function。このように、Python2のprintステートメントの代わりにPython3print関数を使用します。次に、印刷機能を再定義できます。

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

落とし穴がありますが、印刷機能を使い始める必要があります。

于 2013-02-20T17:52:45.273 に答える