擅长:python、mysql、java
<p>除了提升<code>SystemExit</code>之外,还有3个退出函数。</p>
<p>底层的是<code>os._exit</code>,它需要1个int参数,并且不需要清除就立即退出。你不太可能想碰这个,但它就在那儿。</p>
<p><code>sys.exit</code>是在sysmodule.c中定义的,只运行<code>PyErr_SetObject(PyExc_SystemExit, exit_code);</code>,这实际上等同于直接提升<code>SystemExit</code>。详细地说,提高<code>SystemExit</code>可能更快,因为<code>sys.exit</code>需要<code>LOAD_ATTR</code>和<code>CALL_FUNCTION</code>对<code>RAISE_VARARGS</code>操作调用。另外,<code>raise SystemExit</code>生成的字节码稍小(少了4字节),(如果使用<code>from sys import exit</code>则额外生成1字节,因为<code>sys.exit</code>预期返回None,因此包含一个额外的<code>POP_TOP</code>)。</p>
<p>最后一个exit函数在<code>site.py</code>中定义,并在REPL中别名为<code>exit</code>或<code>quit</code>。它实际上是<code>Quitter</code>类的一个实例(因此它可以有一个自定义的<code>__repr__</code>,因此可能是运行最慢的。另外,它在提升<code>SystemExit</code>之前关闭<code>sys.stdin</code>,因此建议仅在REPL中使用。</p>
<p>至于<code>SystemExit</code>是如何处理的,它最终会导致VM调用os.\u exit,但在此之前,它会进行一些清理。它还运行<code>atexit._run_exitfuncs()</code>,运行通过<code>atexit</code>模块注册的任何回调。调用<code>os._exit</code>直接绕过<code>atexit</code>步骤。</p>