在没有提示的情况下关闭 Python IDLE shell

Close Python IDLE shell without prompt

我正在处理一个脚本(脚本 A),它需要打开一个新的 Python IDLE shell,自动 运行 在其中打开另一个脚本(脚本 B),然后关闭它。以下代码是我用于此目的的代码:

import sys
sys.argv=['','-n','-t','My New Shell','-c','execfile("VarLoader.py")']
import idlelib.PyShell
idlelib.PyShell.main()

但是我无法让新的 shell 自动关闭。我已尝试将以下内容添加到脚本 B,但要么它没有关闭新的 shell,要么弹出 windows 询问我是否要杀死它。

exit()

.

import sys
sys.exit()

我建议您创建一个覆盖 closePyShell 的子 class,而不是修改 IDLE 源代码以使您的程序跳过提示退出方法你希望它如何工作:

import idlelib.PyShell
class PyShell_NoExitPrompt(idlelib.PyShell.PyShell):
    def close(self):
        "Extend EditorWindow.close(), does not prompt to exit"
##        if self.executing:
##            response = tkMessageBox.askokcancel(
##                "Kill?",
##                "Your program is still running!\n Do you want to kill it?",
##                default="ok",
##                parent=self.text)
##            if response is False:
##                return "cancel"
        self.stop_readline()
        self.canceled = True
        self.closing = True
        return idlelib.PyShell.EditorWindow.close(self)

最初的问题是使用 idlelib.PyShell.main 不会使用你的子class,你实际上可以创建一个 copy 函数- 不修改原件 - 通过使用 FunctionType 构造函数,该构造函数将使用您修改后的 class:

import functools
from types import FunctionType

def copy_function(f, namespace_override):
    """creates a copy of a function (code, signature, defaults) with a modified global scope"""
    namespace = dict(f.__globals__)
    namespace.update(namespace_override)
    new_f = FunctionType(f.__code__, namespace, f.__name__, f.__defaults__, f.__closure__)
    return functools.update_wrapper(f, new_f)

然后你可以 运行 你的额外 IDLE shell 像这样:

import sys
#there is also a way to prevent the need to override sys.argv but that isn't as concerning to me.
sys.argv = ['','-n','-t','My New Shell','-c','execfile("VarLoader.py")']
hacked_main = copy_function(idlelib.PyShell.main,
                            {"PyShell":PyShell_NoExitPrompt})

hacked_main()

现在您可以让 IDLE 保持原样,让您的程序也按您希望的方式运行。 (也兼容其他版本的python!)