我正在用 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'
目标是模仿这种行为,打印一些无,而不是其他(稍微复杂一些,因为我不完全确定规则是什么)。
所以,转向我的程序,我有 history_text 和 entry_text,它们是 StringVar(),它们控制 Tk 窗口中输入框上方的标签。然后将以下事件绑定到 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 的一些文档,它似乎控制解释器何时实际显示结果,但我不确定如何在这里使用它。我以为我可以将 sys.displayhook() 包裹在我的 exec() 调用周围,让它为我完成所有这些工作......但发现它并不意味着像 '3 + 4' 这样的语句的 print() 语句或'3'。
有什么建议么?我在 sys.displayhook 的正确轨道上吗?