uTools-Manuals/docs/python/atexit.html
2019-04-21 11:50:48 +08:00

30 lines
10 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<div class="body" role="main"><div class="section" id="module-atexit"><h1><span class="yiyi-st" id="yiyi-10">29.8. <a class="reference internal" href="#module-atexit" title="atexit: Register and execute cleanup functions."><code class="xref py py-mod docutils literal"><span class="pre">atexit</span></code></a> - 退出处理程序</span></h1><p><span class="yiyi-st" id="yiyi-11"><a class="reference internal" href="#module-atexit" title="atexit: Register and execute cleanup functions."><code class="xref py py-mod docutils literal"><span class="pre">atexit</span></code></a>模块定义了注册和注销清除函数的函数。</span><span class="yiyi-st" id="yiyi-12">这样注册的函数在正常解释器终止时自动执行。</span><span class="yiyi-st" id="yiyi-13"><a class="reference internal" href="#module-atexit" title="atexit: Register and execute cleanup functions."><code class="xref py py-mod docutils literal"><span class="pre">atexit</span></code></a> 运行这些函数以它们注册顺序 <em>逆向</em> 顺序运行; 当你注册 <code class="docutils literal"><span class="pre">A</span></code>, <code class="docutils literal"><span class="pre">B</span></code>, 和<code class="docutils literal"><span class="pre">C</span></code>, 解释器结束时他们的运行顺序是: <code class="docutils literal"><span class="pre">C</span></code>, <code class="docutils literal"><span class="pre">B</span></code>, <code class="docutils literal"><span class="pre">A</span></code>.</span></p><p><span class="yiyi-st" id="yiyi-14"><strong>注意:</strong>当检测到Python致命内部错误时或当<a class="reference internal" href="os.html#os._exit" title="os._exit"><code class="xref py py-func docutils literal"><span class="pre">os._exit()</span></code></a></span></p><dl class="function"><dt id="atexit.register"><span class="yiyi-st" id="yiyi-15"> <code class="descclassname">atexit.</code><code class="descname">register</code><span class="sig-paren">(</span><em>func</em>, <em>*args</em>, <em>**kargs</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-16"><em>func</em>寄存器作为要在终止时执行的函数。</span><span class="yiyi-st" id="yiyi-17">任何传递给<em>func</em>的可选参数必须作为参数传递给<a class="reference internal" href="#atexit.register" title="atexit.register"><code class="xref py py-func docutils literal"><span class="pre">register()</span></code></a></span><span class="yiyi-st" id="yiyi-18">可以多次注册相同的函数和参数。</span></p><p><span class="yiyi-st" id="yiyi-19">在正常的程序终止(对于实例,如果<a class="reference internal" href="sys.html#sys.exit" title="sys.exit"><code class="xref py py-func docutils literal"><span class="pre">sys.exit()</span></code></a>被调用或主模块的执行完成),所有注册的函数以最后进先出的顺序调用。</span><span class="yiyi-st" id="yiyi-20">假设较低级别模块通常在较高级别模块之前导入,因此必须以后进行清理。</span></p><p><span class="yiyi-st" id="yiyi-21">如果在执行退出处理程序期间引发异常,则会打印回溯(除非引发<a class="reference internal" href="exceptions.html#SystemExit" title="SystemExit"><code class="xref py py-exc docutils literal"><span class="pre">SystemExit</span></code></a>),并保存异常信息。</span><span class="yiyi-st" id="yiyi-22">在所有退出处理程序有机会运行后,最后一个异常被提出是重新提出。</span></p><p><span class="yiyi-st" id="yiyi-23">此函数返回<em>func</em>,这使得它可以用作装饰器。</span></p></dd></dl><dl class="function"><dt id="atexit.unregister"><span class="yiyi-st" id="yiyi-24"> <code class="descclassname">atexit.</code><code class="descname">unregister</code><span class="sig-paren">(</span><em>func</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-25">从要在解释器关机运行的函数列表中删除<em>func</em></span><span class="yiyi-st" id="yiyi-26">调用<a class="reference internal" href="#atexit.unregister" title="atexit.unregister"><code class="xref py py-func docutils literal"><span class="pre">unregister()</span></code></a>后,即使解释器关闭,即使注册了多次,也保证不会调用<em>func</em></span><span class="yiyi-st" id="yiyi-27"><a class="reference internal" href="#atexit.unregister" title="atexit.unregister"><code class="xref py py-func docutils literal"><span class="pre">unregister()</span></code></a>如果<em>func</em>之前未注册,则默认不执行任何操作。</span></p></dd></dl><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-28">也可以看看</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-29">模块<a class="reference internal" href="readline.html#module-readline" title="readline: GNU readline support for Python. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">readline</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-30"><a class="reference internal" href="#module-atexit" title="atexit: Register and execute cleanup functions."><code class="xref py py-mod docutils literal"><span class="pre">atexit</span></code></a>读取和写入<a class="reference internal" href="readline.html#module-readline" title="readline: GNU readline support for Python. (Unix)"><code class="xref py py-mod docutils literal"><span class="pre">readline</span></code></a>历史记录文件的有用示例。</span></dd></dl></div><div class="section" id="atexit-example"><h2><span class="yiyi-st" id="yiyi-31">29.8.1. <a class="reference internal" href="#module-atexit" title="atexit: Register and execute cleanup functions."><code class="xref py py-mod docutils literal"><span class="pre">atexit</span></code></a>示例</span></h2><p><span class="yiyi-st" id="yiyi-32">以下简单示例演示了模块如何在导入时从文件初始化计数器,并在程序终止时自动保存计数器的更新值,而不依赖于在终止时明确调用该模块的应用程序。</span></p><pre><code class="language-python"><span></span><span class="k">try</span><span class="p">:</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"counterfile"</span><span class="p">)</span> <span class="k">as</span> <span class="n">infile</span><span class="p">:</span>
<span class="n">_count</span> <span class="o">=</span> <span class="nb">int</span><span class="p">(</span><span class="n">infile</span><span class="o">.</span><span class="n">read</span><span class="p">())</span>
<span class="k">except</span> <span class="ne">FileNotFoundError</span><span class="p">:</span>
<span class="n">_count</span> <span class="o">=</span> <span class="mi">0</span>
<span class="k">def</span> <span class="nf">incrcounter</span><span class="p">(</span><span class="n">n</span><span class="p">):</span>
<span class="k">global</span> <span class="n">_count</span>
<span class="n">_count</span> <span class="o">=</span> <span class="n">_count</span> <span class="o">+</span> <span class="n">n</span>
<span class="k">def</span> <span class="nf">savecounter</span><span class="p">():</span>
<span class="k">with</span> <span class="nb">open</span><span class="p">(</span><span class="s2">"counterfile"</span><span class="p">,</span> <span class="s2">"w"</span><span class="p">)</span> <span class="k">as</span> <span class="n">outfile</span><span class="p">:</span>
<span class="n">outfile</span><span class="o">.</span><span class="n">write</span><span class="p">(</span><span class="s2">"</span><span class="si">%d</span><span class="s2">"</span> <span class="o">%</span> <span class="n">_count</span><span class="p">)</span>
<span class="kn">import</span> <span class="nn">atexit</span>
<span class="n">atexit</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">savecounter</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-33">位置和关键字参数也可以传递到<a class="reference internal" href="#atexit.register" title="atexit.register"><code class="xref py py-func docutils literal"><span class="pre">register()</span></code></a>,以便在调用时传递给注册函数:</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">goodbye</span><span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">adjective</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="s1">'Goodbye, </span><span class="si">%s</span><span class="s1">, it was </span><span class="si">%s</span><span class="s1"> to meet you.'</span> <span class="o">%</span> <span class="p">(</span><span class="n">name</span><span class="p">,</span> <span class="n">adjective</span><span class="p">))</span>
<span class="kn">import</span> <span class="nn">atexit</span>
<span class="n">atexit</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">goodbye</span><span class="p">,</span> <span class="s1">'Donny'</span><span class="p">,</span> <span class="s1">'nice'</span><span class="p">)</span>
<span class="c1"># or:</span>
<span class="n">atexit</span><span class="o">.</span><span class="n">register</span><span class="p">(</span><span class="n">goodbye</span><span class="p">,</span> <span class="n">adjective</span><span class="o">=</span><span class="s1">'nice'</span><span class="p">,</span> <span class="n">name</span><span class="o">=</span><span class="s1">'Donny'</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-34">用作<a class="reference internal" href="../glossary.html#term-decorator"><span class="xref std std-term">decorator</span></a></span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">atexit</span>
<span class="nd">@atexit</span><span class="o">.</span><span class="n">register</span>
<span class="k">def</span> <span class="nf">goodbye</span><span class="p">():</span>
<span class="nb">print</span><span class="p">(</span><span class="s2">"You are now leaving the Python sector."</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-35">这只适用于可以在没有参数的情况下调用的函数。</span></p></div></div></div>