Python诅咒困境

mat*_*ots 10 python curses ncurses

我正在玩Python和诅咒.

我跑的时候

import time
import curses

def main():
    curses.initscr()
    curses.cbreak()
    for i in range(3):
        time.sleep(1)
        curses.flash()
        pass
    print( "Hello World" )
    curses.endwin()

if __name__ == '__main__':
    main()
Run Code Online (Sandbox Code Playgroud)

如果我一直等待,curses.endwin()就会被调用,所以一切正常.但是,如果我用Ctrl-C剪短它,curses.endwin()永远不会被调用,所以它搞砸了我的终端会话.

处理这种情况的正确方法是什么?我怎样才能确保无论我如何尝试结束/中断程序(例如Ctrl-C,Ctrl-Z),它都不会弄乱终端?

Hen*_*ren 47

我相信您正在寻找curses.wrapper请参阅http://docs.python.org/dev/library/curses.html#curses.wrapper

它将在init上执行curses.cbreak(),curses.noecho()和curses_screen.keypad(1)并在退出时反转它们,即使退出是异常.

您的程序作为包装器的函数,例如:

def main(screen):
    """screen is a curses screen passed from the wrapper"""
    ...

if __name__ == '__main__':
    curses.wrapper(main)
Run Code Online (Sandbox Code Playgroud)


orl*_*rlp 8

你可以这样做:

def main():
    curses.initscr()

    try:
        curses.cbreak()
        for i in range(3):
            time.sleep(1)
            curses.flash()
            pass
        print( "Hello World" )
    finally:
        curses.endwin()
Run Code Online (Sandbox Code Playgroud)

或者更好的是,创建一个上下文包装器:

class CursesWindow(object):
    def __enter__(self):
        curses.initscr()

    def __exit__(self):
        curses.endwin()

def main():
    with CursesWindow():
        curses.cbreak()
        for i in range(3):
            time.sleep(1)
            curses.flash()
            pass
        print( "Hello World" )
Run Code Online (Sandbox Code Playgroud)