mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-08 15:04:05 +08:00
30 lines
10 KiB
HTML
30 lines
10 KiB
HTML
<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> |