1

私はTkで小さなおもちゃのコマンドウィンドウを作成していて、現在、インタプリタの動作をコピーさせようとしています。

私はこれまで通訳者を精査したことはありませんでしたが、値をいつ印刷するかについての決定は少し神秘的です。

>>> 3 + 4  # implied print(...)
7
>>> 3      # implied print(...)
3
>>> a = 3  # no output, no implied print(...), bc result is None maybe?
>>> None   # no output, no print(...) implied... doesn't like None?
>>> print(None)  # but it doesn't just ban all Nones, allows explicit print()
None
>>> str(None) # unsurprising, the string 'None' is just a string, and echoed
'None'

目標は、この動作を模倣して、他のNoneではなく一部のNoneを印刷することです(ルールが何であるか完全にわからないため、少し複雑になります)。

したがって、私のプログラムに目を向けると、history_textとentry_textがあります。これらは、Tkウィンドウの入力ボックスの上のラベルを制御するStringVar()です。次に、次のイベントがReturnキーにバインドされ、コマンドを処理して履歴を結果で更新します。

def to_history(event):
    print("command entered")  # note to debugging window

    last_history = history_text.get()

    # hijack stdout
    buffer = io.StringIO('')
    sys.stdout = buffer

    # run command, output to buffer
    exec(entry_text.get())

    # buffered output to a simple string
    buffer.seek(0)
    buffer_str = ''
    for line in buffer.readlines():
        # maybe some rule goes here to decide if an implied 'print(...)' is needed
        buffer_str = buffer_str + line + '\n'

    # append typed command for echo
    new_history = entry_text.get() + '\n' + buffer_str

    # cleanup (let stdout go home)
    sys.stdout = sys.__stdout__
    buffer.close()

    history_text.set(last_history + "\n" + new_history)
    entry_text.set('')

現状では、「3」または「なし」、さらには「3+4」の単純なエントリの出力は提供されません。暗黙のprint()ステートメントを常に追加すると、印刷が頻繁に行われるようです。「None」または「a=3」タイプのステートメントの印刷をスキップしません。

通訳者が実際に結果を表示するタイミングを管理しているように見えるsys.displayhookのドキュメントをいくつか見つけましたが、ここでの使用方法がわかりません。exec()呼び出しの周りにsys.displayhook()をラップして、このすべての作業を実行させることができると思いました...しかし、「3 +4」や「3」。

助言がありますか?私はsys.displayhookで正しい方向に進んでいますか?

4

1 に答える 1

3

インタプリタは、のrepr(result)場合にのみ出力しresult is not Noneます。

printあなたが思ったような「暗黙の」はありません。

  • 3 + 4結果をに7、したがってrepr(7)印刷されます
  • a = 3課題ですが、動作しないので何も印刷されないと思いますeval
  • None結果がになりNone、何も出力されません
  • print(None)結果はNoneprint関数が何も返さないため)になり、何も出力されません。ただし、print関数自体はを出力しましたNone

私は正直にあなたのコードを読んでいませんでしたが、コードを含む文字列を受け取り、インタプリタと同じ出力を生成する関数を次に示します。

def interactive(code):
    try:
        result = eval(code)
        if result is not None:
            print(repr(result))
    except SyntaxError:
        exec(code)
于 2012-09-03T13:26:31.883 に答える