2017-12-18 26 views
1

私は、Python REPLのすべての出力を上書きして解析する方法を探しています。たとえば、端末のqtconsoleにあるpython/IPythonです。REPL出力を無効にする

これは、印刷機能を無効にすることによって、印刷されたテキストでは簡単です。簡単な例では、我々はすべての出力に感嘆符を追加したいと言う:

orig_print = print 
print = lambda text: orig_print(text + '!') 

今すぐすべての印刷コマンドが追加感嘆符を持つことになります。これをリセットするには、

del print 

質問:どのようにREPL出力に相当するのですか?たとえば、私はどうすればこの機能が働くのでしょうか?

In[1]: 5 + 5 
Out[2]: 10! 

検索はcontextlib、サブプロセスおよびsys.stdoutのパスの下に私を導いてきたが、私は解決策を見つけるしたことはありません。 sympyの印刷モジュールをGithubで調べましたが、成功しませんでした。

+0

うーん...多分これは、それは ''次の行に変更され 'TMP(テキストを修正することが可能です –

答えて

2

私はちょうどsys.stdout.writeを上書きしようとしましたが、(いくつかの癖を付けて)機能しました。私が間違っていると誰かが私を訂正しますが、これよりずっと良くなるとは思えません。

In [1]: import sys 

In [2]: tmp = sys.stdout.write 

In [3]: sys.stdout.write = lambda text: tmp(text + '!') 

In [4]: 5 + 5 
!Out[4]: 10! 
!! 
!!In [5]: 

編集:私はこれまでのところ得ている
。 1つ余分に!がどこから来たのか分からない。

In [5]: sys.stdout.write = lambda text: tmp(text if text.endswith('\n') else text + '!\r') 

In [6]: 5+5 
Out[6]: 10! 
! 
In [7]: 
+0

をsys.settrace''で可能です+ – DeepSpace

+0

私の特定のユースケースでは、この異常(余分な!)が出てこなかった:あなたのソリューションはそのまま動作する! –

+0

誰かがIPython qtconsoleで同等のアイデアを持っていますか? sys.stdoutを使用しないように見えます。私はipykernel.iostream.OutStream.writeとIPython.sys.stdout.writeを試みました。 –

0

this articleに基づくIPython QtConsoleで動作する例です。これはorangeinkのソリューションオーバーライド標準出力と組み合わせて使用​​されています!

class SciNum: 
    """For compatibility with IPython's pretty printer: Contains a string, 
    with a REPR that allows pretty() to print without quotes, as it would 
    if using the string directly.""" 
    def __init__(self, text: str): 
     self.text = text 

    def __repr__(self): 
     return self.text 


def _print_ipython(arg, p, cycle) -> None: 
    """Uses IPython's pretty printer to modify output for a qtconsole or notebook; 
    stdout doesn't seem to work for them.""" 
    p.text(IPython.lib.pretty.pretty(SciNum(format(arg)))) 

def start() -> None: 
    if not ipython_exists: 
     return 

    ip = IPython.get_ipython() 
    # We only need to handle IPython separately if in a Qtconsole or Notebook. 
    if isinstance(ip, IPython.terminal.interactiveshell.TerminalInteractiveShell): 
     return 

    text_formatter = ip.display_formatter.formatters['text/plain'] 

    text_formatter.for_type(float, _print_ipython) 
    text_formatter.for_type(int, _print_ipython) 
関連する問題