Emacs:Inferior-mode Python-Shell 出现“滞后”问题

6
我是一个Python(3.1.2)/emacs(23.2)新手,正在使用在这里找到的pythonware教程自学tkinter。相关代码已粘贴在问题下面。

问题:当我点击Hello按钮(应该调用say_hi函数)时,为什么劣质的python shell(即我用C-c C-c启动的那个)要等到我单击Quit按钮或关闭根部组件之前才执行say_hi打印函数?在IDLE中尝试相同操作时,每次单击Hello按钮都会立即在IDLE python shell中打印,甚至在我单击Quit或关闭根组件之前就会打印。

是否有一些emacs运行Python shell(与IDLE相比)的怪癖导致了这种“滞后”行为?当我通过Project Euler问题进行工作时,我已经注意到类似的emacs滞后与IDLE,但这是我迄今所见过的最清晰的例子。

FYI:我使用python.el并拥有一个相对干净的init.el...

(setq python-python-command "d:/bin/python31/python")

是我init.el中唯一的一行。

谢谢,

Mike

=== 开始代码 ===

from tkinter import *

class App:

    def __init__(self,master):

        frame = Frame(master)
        frame.pack()

        self.button = Button(frame, text="QUIT", fg="red", command=frame.quit)
        self.button.pack(side=LEFT)

        self.hi_there = Button(frame, text="Hello", command=self.say_hi)
        self.hi_there.pack(side=LEFT)

    def say_hi(self):
        print("hi there, everyone!")

root = Tk()

app = App(root)

root.mainloop()

尝试使用print('abc', file=sys.stderr),可能是缓冲问题(输出到控制台可能是行缓冲,但输出到管道/文件可能有固定缓冲区)。 - jfs
没有用。sys.stdout.flush() [下面是 msw 的回答] 有用。谢谢你的评论! - MikeRand
1个回答

4
我猜想,由于Python解释器(通过C标准输入输出)未连接到tty,它会从行缓冲切换到块缓冲,并且直到关闭后才会刷新stdout。在“Inferior Python:run Shell Compile”缓冲区中运行os.isatty(1)会返回false,因此支持这个猜测。
def say_hi(self):
    print("hi there, everyone!")
    sys.stdout.flush()

可能会有所不同。


那个在打印问题上起作用了。由于某种奇怪的原因,较差的缓冲区在退出/关闭时会挂起。虽然是另一个问题,但非常感谢您的帮助。 - MikeRand
Tkinter中的事件循环具有一些奇怪的属性,我从未深入探索过。我知道在IDLE下使用Tkinter会表现出奇怪的行为,我猜测这是由于竞争事件循环引起的。 - msw
好的观点...等我变得更加熟练时再来看。再次感谢。 - MikeRand

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接