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

26 lines
42 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-warnings"><h1><span class="yiyi-st" id="yiyi-10">29.5. <a class="reference internal" href="#module-warnings" title="warnings: Issue warning messages and control their disposition."><code class="xref py py-mod docutils literal"><span class="pre">warnings</span></code></a> - 警告控制</span></h1><p><span class="yiyi-st" id="yiyi-11"><strong>源代码:</strong> <a class="reference external" href="https://hg.python.org/cpython/file/3.5/Lib/warnings.py">Lib / warnings.py</a></span></p><p><span class="yiyi-st" id="yiyi-12">警告消息通常在以下情况下发出,其中警告用户在程序中的某些条件是有用的,其中该条件(通常)不需要提出异常并终止程序。</span><span class="yiyi-st" id="yiyi-13">例如,当程序使用过时的模块时,可能需要发出警告。</span></p><p><span class="yiyi-st" id="yiyi-14">Python程序员通过调用此模块中定义的<a class="reference internal" href="#warnings.warn" title="warnings.warn"><code class="xref py py-func docutils literal"><span class="pre">warn()</span></code></a>函数来发出警告。</span><span class="yiyi-st" id="yiyi-15">C程序员使用<a class="reference internal" href="../c-api/exceptions.html#c.PyErr_WarnEx" title="PyErr_WarnEx"><code class="xref c c-func docutils literal"><span class="pre">PyErr_WarnEx()</span></code></a>;有关详细信息,请参阅<a class="reference internal" href="../c-api/exceptions.html#exceptionhandling"><span>Exception Handling</span></a>)。</span></p><p><span class="yiyi-st" id="yiyi-16">警告消息通常写入<code class="docutils literal"><span class="pre">sys.stderr</span></code>,但它们的处置可以灵活更改,从忽略所有警告,将其转换为异常。</span><span class="yiyi-st" id="yiyi-17">警告的处理可以根据警告类别(见下文),警告消息的文本以及发出警告消息的源位置而变化。</span><span class="yiyi-st" id="yiyi-18">对于相同源位置的特定警告的重复通常被抑制。</span></p><p><span class="yiyi-st" id="yiyi-19">在警告控制中有两个阶段:首先,每次发出警告时,确定是否应该发出消息;接下来,如果要发出消息,则使用用户可设置的挂钩来格式化和打印消息。</span></p><p><span class="yiyi-st" id="yiyi-20">警告过滤器控制是否发出警告消息的确定,该警告过滤器是匹配规则和动作的序列。</span><span class="yiyi-st" id="yiyi-21">可以通过调用<a class="reference internal" href="#warnings.filterwarnings" title="warnings.filterwarnings"><code class="xref py py-func docutils literal"><span class="pre">filterwarnings()</span></code></a>将规则添加到过滤器,并通过调用<a class="reference internal" href="#warnings.resetwarnings" title="warnings.resetwarnings"><code class="xref py py-func docutils literal"><span class="pre">resetwarnings()</span></code></a>将其重置为默认状态。</span></p><p><span class="yiyi-st" id="yiyi-22">警告消息的打印通过调用<a class="reference internal" href="#warnings.showwarning" title="warnings.showwarning"><code class="xref py py-func docutils literal"><span class="pre">showwarning()</span></code></a>完成,可能会被覆盖;此函数的默认实现通过调用<a class="reference internal" href="#warnings.formatwarning" title="warnings.formatwarning"><code class="xref py py-func docutils literal"><span class="pre">formatwarning()</span></code></a>格式化消息,这也可以由自定义实现使用。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-23">也可以看看</span></p><p class="last"><span class="yiyi-st" id="yiyi-24"><a class="reference internal" href="logging.html#logging.captureWarnings" title="logging.captureWarnings"><code class="xref py py-func docutils literal"><span class="pre">logging.captureWarnings()</span></code></a>允许您使用标准日志记录基础结构处理所有警告。</span></p></div><div class="section" id="warning-categories"><h2><span class="yiyi-st" id="yiyi-25">29.5.1. </span><span class="yiyi-st" id="yiyi-26">Warning Categories</span></h2><p><span class="yiyi-st" id="yiyi-27">有一些代表警告类别的内建异常。</span><span class="yiyi-st" id="yiyi-28">这种分类对于能够过滤掉警告组是有用的。</span><span class="yiyi-st" id="yiyi-29">当前定义了以下警告类别类:</span></p><table border="1" class="docutils"><thead valign="bottom"><tr class="row-odd"><th class="head"><span class="yiyi-st" id="yiyi-30"></span></th><th class="head"><span class="yiyi-st" id="yiyi-31">描述</span></th></tr></thead><tbody valign="top"><tr class="row-even"><td><span class="yiyi-st" id="yiyi-32"><a class="reference internal" href="exceptions.html#Warning" title="Warning"><code class="xref py py-exc docutils literal"><span class="pre">Warning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-33">这是所有警告类别类的基类。</span><span class="yiyi-st" id="yiyi-34">它是<a class="reference internal" href="exceptions.html#Exception" title="Exception"><code class="xref py py-exc docutils literal"><span class="pre">Exception</span></code></a>的子类。</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-35"><a class="reference internal" href="exceptions.html#UserWarning" title="UserWarning"><code class="xref py py-exc docutils literal"><span class="pre">UserWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-36"><a class="reference internal" href="#warnings.warn" title="warnings.warn"><code class="xref py py-func docutils literal"><span class="pre">warn()</span></code></a>的默认类别。</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-37"><a class="reference internal" href="exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal"><span class="pre">DeprecationWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-38">用于关于已弃用功能的警告的基本类别(默认情况下已忽略)。</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-39"><a class="reference internal" href="exceptions.html#SyntaxWarning" title="SyntaxWarning"><code class="xref py py-exc docutils literal"><span class="pre">SyntaxWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-40">基本类别用于关于可疑句法特征的警告。</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-41"><a class="reference internal" href="exceptions.html#RuntimeWarning" title="RuntimeWarning"><code class="xref py py-exc docutils literal"><span class="pre">RuntimeWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-42">用于有关可疑运行时功能的警告的基本类别。</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-43"><a class="reference internal" href="exceptions.html#FutureWarning" title="FutureWarning"><code class="xref py py-exc docutils literal"><span class="pre">FutureWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-44">对于将来会在语义上更改的构造的警告的基本类别。</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-45"><a class="reference internal" href="exceptions.html#PendingDeprecationWarning" title="PendingDeprecationWarning"><code class="xref py py-exc docutils literal"><span class="pre">PendingDeprecationWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-46">对于将来将被弃用的功能的警告的基本类别(默认情况下将被忽略)。</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-47"><a class="reference internal" href="exceptions.html#ImportWarning" title="ImportWarning"><code class="xref py py-exc docutils literal"><span class="pre">ImportWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-48">导入模块过程中触发的警告的基本类别(默认情况下忽略)。</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-49"><a class="reference internal" href="exceptions.html#UnicodeWarning" title="UnicodeWarning"><code class="xref py py-exc docutils literal"><span class="pre">UnicodeWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-50">与Unicode相关的警告的基本类别。</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-51"><a class="reference internal" href="exceptions.html#BytesWarning" title="BytesWarning"><code class="xref py py-exc docutils literal"><span class="pre">BytesWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-52"><a class="reference internal" href="functions.html#bytes" title="bytes"><code class="xref py py-class docutils literal"><span class="pre">bytes</span></code></a><a class="reference internal" href="functions.html#bytearray" title="bytearray"><code class="xref py py-class docutils literal"><span class="pre">bytearray</span></code></a>相关的警告的基本类别。</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-53"><a class="reference internal" href="exceptions.html#ResourceWarning" title="ResourceWarning"><code class="xref py py-exc docutils literal"><span class="pre">ResourceWarning</span></code></a></span></td><td><span class="yiyi-st" id="yiyi-54">与资源使用相关的警告的基本类别。</span></td></tr></tbody></table><p><span class="yiyi-st" id="yiyi-55">虽然这些是技术上的内建异常,它们在这里被记录,因为在概念上它们属于警告机制。</span></p><p><span class="yiyi-st" id="yiyi-56">用户代码可以通过对一个标准警告类别进行子类化来定义其他警告类别。</span><span class="yiyi-st" id="yiyi-57">警告类别必须始终是<a class="reference internal" href="exceptions.html#Warning" title="Warning"><code class="xref py py-exc docutils literal"><span class="pre">Warning</span></code></a>类的子类。</span></p></div><div class="section" id="the-warnings-filter"><h2><span class="yiyi-st" id="yiyi-58">29.5.2. </span><span class="yiyi-st" id="yiyi-59">The Warnings Filter</span></h2><p><span class="yiyi-st" id="yiyi-60">warnings过滤器控制是否忽略显示或转换为错误引发异常</span></p><p><span class="yiyi-st" id="yiyi-61">在概念上,警告过滤器维护过滤器规格的有序列表;任何特定的警告将依次与列表中的每个过滤器规范匹配,直到找到匹配为止;匹配确定匹配的处置。</span><span class="yiyi-st" id="yiyi-62">每个条目是形式(<em>动作</em><em>消息</em><em>类别</em><em>模块</em><em>/ t4&gt;),其中:</em></span></p><ul><li><p class="first"><span class="yiyi-st" id="yiyi-63"><em>action</em>是以下字符串之一:</span></p><table border="1" class="docutils"><thead valign="bottom"><tr class="row-odd"><th class="head"><span class="yiyi-st" id="yiyi-64"></span></th><th class="head"><span class="yiyi-st" id="yiyi-65">处置</span></th></tr></thead><tbody valign="top"><tr class="row-even"><td><span class="yiyi-st" id="yiyi-66"><code class="docutils literal"><span class="pre">"error"</span></code></span></td><td><span class="yiyi-st" id="yiyi-67">将匹配警告转换为异常</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-68"><code class="docutils literal"><span class="pre">"ignore"</span></code></span></td><td><span class="yiyi-st" id="yiyi-69">从不打印匹配的警告</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-70"><code class="docutils literal"><span class="pre">"always"</span></code></span></td><td><span class="yiyi-st" id="yiyi-71">始终打印匹配的警告</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-72"><code class="docutils literal"><span class="pre">"default"</span></code></span></td><td><span class="yiyi-st" id="yiyi-73">为发出警告的每个位置打印匹配警告的第一次出现</span></td></tr><tr class="row-even"><td><span class="yiyi-st" id="yiyi-74"><code class="docutils literal"><span class="pre">"module"</span></code></span></td><td><span class="yiyi-st" id="yiyi-75">为发出警告的每个模块打印第一次出现的匹配警告</span></td></tr><tr class="row-odd"><td><span class="yiyi-st" id="yiyi-76"><code class="docutils literal"><span class="pre">"once"</span></code></span></td><td><span class="yiyi-st" id="yiyi-77">只打印匹配警告的第一次出现,而不考虑位置</span></td></tr></tbody></table></li><li><p class="first"><span class="yiyi-st" id="yiyi-78"><em>message</em>是包含正则表达式的字符串,警告消息的开头必须匹配。</span><span class="yiyi-st" id="yiyi-79">表达式编译为始终不区分大小写。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-80"><em>category</em>是一个类(<a class="reference internal" href="exceptions.html#Warning" title="Warning"><code class="xref py py-exc docutils literal"><span class="pre">Warning</span></code></a>的子类),其中警告类别必须是子类才能匹配。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-81"><em>模块</em>是包含模块名称必须匹配的正则表达式的字符串。</span><span class="yiyi-st" id="yiyi-82">表达式编译为区分大小写。</span></p></li><li><p class="first"><span class="yiyi-st" id="yiyi-83"><em>lineno</em>是一个整数,警告发生的行号必须匹配,或<code class="docutils literal"><span class="pre">0</span></code>匹配所有行号。</span></p></li></ul><p><span class="yiyi-st" id="yiyi-84">由于<a class="reference internal" href="exceptions.html#Warning" title="Warning"><code class="xref py py-exc docutils literal"><span class="pre">Warning</span></code></a>类派生自内建<a class="reference internal" href="exceptions.html#Exception" title="Exception"><code class="xref py py-exc docutils literal"><span class="pre">Exception</span></code></a>类,要将警告转为错误,我们只需引入<code class="docutils literal"><span class="pre">category(message)</span></code></span></p><p><span class="yiyi-st" id="yiyi-85">警告过滤器由传递到Python解释器命令行的<a class="reference internal" href="../using/cmdline.html#cmdoption-W"><code class="xref std std-option docutils literal"><span class="pre">-W</span></code></a>选项初始化。</span><span class="yiyi-st" id="yiyi-86">解释器保存<code class="docutils literal"><span class="pre">sys.warnoptions</span></code>中所有<a class="reference internal" href="../using/cmdline.html#cmdoption-W"><code class="xref std std-option docutils literal"><span class="pre">-W</span></code></a>选项的参数,而不解释; <a class="reference internal" href="#module-warnings" title="warnings: Issue warning messages and control their disposition."><code class="xref py py-mod docutils literal"><span class="pre">warnings</span></code></a>模块会在首次导入时解析这些(在将消息打印到<code class="docutils literal"><span class="pre">sys.stderr</span></code>之后,会忽略无效选项)。</span></p><div class="section" id="default-warning-filters"><h3><span class="yiyi-st" id="yiyi-87">29.5.2.1. </span><span class="yiyi-st" id="yiyi-88">Default Warning Filters</span></h3><p><span class="yiyi-st" id="yiyi-89">默认情况下Python安装了几个警告过滤器可以通过传递给<a class="reference internal" href="../using/cmdline.html#cmdoption-W"><code class="xref std std-option docutils literal"><span class="pre">-W</span></code></a>的命令行选项覆盖,并调用<a class="reference internal" href="#warnings.filterwarnings" title="warnings.filterwarnings"><code class="xref py py-func docutils literal"><span class="pre">filterwarnings()</span></code></a></span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-90"><a class="reference internal" href="exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal"><span class="pre">DeprecationWarning</span></code></a><a class="reference internal" href="exceptions.html#PendingDeprecationWarning" title="PendingDeprecationWarning"><code class="xref py py-exc docutils literal"><span class="pre">PendingDeprecationWarning</span></code></a><a class="reference internal" href="exceptions.html#ImportWarning" title="ImportWarning"><code class="xref py py-exc docutils literal"><span class="pre">ImportWarning</span></code></a>将被忽略。</span></li><li><span class="yiyi-st" id="yiyi-91">除非<a class="reference internal" href="../using/cmdline.html#cmdoption-b"><code class="xref std std-option docutils literal"><span class="pre">-b</span></code></a>选项被给定一次或两次; <a class="reference internal" href="exceptions.html#BytesWarning" title="BytesWarning"><code class="xref py py-exc docutils literal"><span class="pre">BytesWarning</span></code></a>在这种情况下,将打印此警告(<code class="docutils literal"><span class="pre">-b</span></code>)或变成异常(<code class="docutils literal"><span class="pre">-bb</span></code>)。</span></li><li><span class="yiyi-st" id="yiyi-92"><a class="reference internal" href="exceptions.html#ResourceWarning" title="ResourceWarning"><code class="xref py py-exc docutils literal"><span class="pre">ResourceWarning</span></code></a>被忽略除非Python是在调试模式下构建的。</span></li></ul><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-93"><span class="versionmodified">Changed in version 3.2: </span><a class="reference internal" href="exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal"><span class="pre">DeprecationWarning</span></code></a> is now ignored by default in addition to <a class="reference internal" href="exceptions.html#PendingDeprecationWarning" title="PendingDeprecationWarning"><code class="xref py py-exc docutils literal"><span class="pre">PendingDeprecationWarning</span></code></a>.</span></p></div></div></div><div class="section" id="temporarily-suppressing-warnings"><h2><span class="yiyi-st" id="yiyi-94">29.5.3. </span><span class="yiyi-st" id="yiyi-95">Temporarily Suppressing Warnings</span></h2><p><span class="yiyi-st" id="yiyi-96">如果您使用的代码已知会引发警告(例如已弃用的函数),但不希望看到该警告,则可以使用<a class="reference internal" href="#warnings.catch_warnings" title="warnings.catch_warnings"><code class="xref py py-class docutils literal"><span class="pre">catch_warnings</span></code></a>上下文管理器取消警告:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">warnings</span>
<span class="k">def</span> <span class="nf">fxn</span><span class="p">():</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">"deprecated"</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">)</span>
<span class="k">with</span> <span class="n">warnings</span><span class="o">.</span><span class="n">catch_warnings</span><span class="p">():</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">simplefilter</span><span class="p">(</span><span class="s2">"ignore"</span><span class="p">)</span>
<span class="n">fxn</span><span class="p">()</span>
</code></pre><p><span class="yiyi-st" id="yiyi-97">在上下文管理器中,所有警告都将被忽略。</span><span class="yiyi-st" id="yiyi-98">这允许您使用已知已弃用的代码,而不必看到警告,而不抑制可能不知道其使用已弃用代码的其他代码的警告。</span><span class="yiyi-st" id="yiyi-99">注意:这只能在单线程应用程序中保证。</span><span class="yiyi-st" id="yiyi-100">如果两个或多个线程同时使用<a class="reference internal" href="#warnings.catch_warnings" title="warnings.catch_warnings"><code class="xref py py-class docutils literal"><span class="pre">catch_warnings</span></code></a>上下文管理器,则该行为是未定义的。</span></p></div><div class="section" id="testing-warnings"><h2><span class="yiyi-st" id="yiyi-101">29.5.4. </span><span class="yiyi-st" id="yiyi-102">Testing Warnings</span></h2><p><span class="yiyi-st" id="yiyi-103">要测试代码引发的警告,请使用<a class="reference internal" href="#warnings.catch_warnings" title="warnings.catch_warnings"><code class="xref py py-class docutils literal"><span class="pre">catch_warnings</span></code></a>上下文管理器。</span><span class="yiyi-st" id="yiyi-104">使用它,您可以临时改变警告过滤器,以方便您的测试。</span><span class="yiyi-st" id="yiyi-105">对于实例,请执行以下操作以捕获所有要检查的升级警告:</span></p><pre><code class="language-python"><span></span><span class="kn">import</span> <span class="nn">warnings</span>
<span class="k">def</span> <span class="nf">fxn</span><span class="p">():</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="s2">"deprecated"</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">)</span>
<span class="k">with</span> <span class="n">warnings</span><span class="o">.</span><span class="n">catch_warnings</span><span class="p">(</span><span class="n">record</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span> <span class="k">as</span> <span class="n">w</span><span class="p">:</span>
<span class="c1"># Cause all warnings to always be triggered.</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">simplefilter</span><span class="p">(</span><span class="s2">"always"</span><span class="p">)</span>
<span class="c1"># Trigger a warning.</span>
<span class="n">fxn</span><span class="p">()</span>
<span class="c1"># Verify some things</span>
<span class="k">assert</span> <span class="nb">len</span><span class="p">(</span><span class="n">w</span><span class="p">)</span> <span class="o">==</span> <span class="mi">1</span>
<span class="k">assert</span> <span class="nb">issubclass</span><span class="p">(</span><span class="n">w</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">category</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">)</span>
<span class="k">assert</span> <span class="s2">"deprecated"</span> <span class="ow">in</span> <span class="nb">str</span><span class="p">(</span><span class="n">w</span><span class="p">[</span><span class="o">-</span><span class="mi">1</span><span class="p">]</span><span class="o">.</span><span class="n">message</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-106">还可以使用<code class="docutils literal"><span class="pre">error</span></code>而不是<code class="docutils literal"><span class="pre">always</span></code>,使所有警告都成为异常。</span><span class="yiyi-st" id="yiyi-107">需要注意的一点是,如果由于<code class="docutils literal"><span class="pre">once</span></code> / <code class="docutils literal"><span class="pre">default</span></code>规则已经出现警告,则无论设置了什么过滤器都不会看到警告再次除非与警告相关的警告注册表已被清除。</span></p><p><span class="yiyi-st" id="yiyi-108">一旦上下文管理器退出,警告过滤器将恢复为其在输入上下文时的状态。</span><span class="yiyi-st" id="yiyi-109">这可防止测试在测试之间以意想不到的方式更改警告过滤器,并导致不确定的测试结果。</span><span class="yiyi-st" id="yiyi-110">模块中的<a class="reference internal" href="#warnings.showwarning" title="warnings.showwarning"><code class="xref py py-func docutils literal"><span class="pre">showwarning()</span></code></a>函数也还原为其原始值。</span><span class="yiyi-st" id="yiyi-111">注意:这只能在单线程应用程序中保证。</span><span class="yiyi-st" id="yiyi-112">如果两个或多个线程同时使用<a class="reference internal" href="#warnings.catch_warnings" title="warnings.catch_warnings"><code class="xref py py-class docutils literal"><span class="pre">catch_warnings</span></code></a>上下文管理器,则该行为是未定义的。</span></p><p><span class="yiyi-st" id="yiyi-113">当测试引发相同类型的警告的多个操作时,重要的是以确认每个操作正在产生新的警告(例如,警告)的方式来测试它们。</span><span class="yiyi-st" id="yiyi-114">设置警告作为异常引发,并检查操作引发异常,检查警告列表的长度在每次操作后继续增加,或者在每次新操作之前从警告列表中删除先前的条目)。</span></p></div><div class="section" id="updating-code-for-new-versions-of-python"><h2><span class="yiyi-st" id="yiyi-115">29.5.5. </span><span class="yiyi-st" id="yiyi-116">Updating Code For New Versions of Python</span></h2><p><span class="yiyi-st" id="yiyi-117">默认情况下会忽略开发人员感兴趣的警告。</span><span class="yiyi-st" id="yiyi-118">因此,你应该确保测试你的代码,通常忽略警告可见。</span><span class="yiyi-st" id="yiyi-119">您可以通过将<a class="reference internal" href="../using/cmdline.html#cmdoption-W"><code class="xref std std-option docutils literal"><span class="pre">-Wd</span></code></a>传递给解释器,从命令行执行此操作(这是<code class="xref std std-option docutils literal"><span class="pre">-W</span> <span class="pre">默认</span> / t3&gt;)。</code></span><span class="yiyi-st" id="yiyi-120">这将为所有警告启用默认处理,包括默认情况下忽略的警告。</span><span class="yiyi-st" id="yiyi-121">要更改遇到的警告所采取的操作,只需更改传递给<a class="reference internal" href="../using/cmdline.html#cmdoption-W"><code class="xref std std-option docutils literal"><span class="pre">-W</span></code></a>的参数即可。</span><span class="yiyi-st" id="yiyi-122"><code class="xref std std-option docutils literal"><span class="pre">-W</span> <span class="pre">错误</span></code></span><span class="yiyi-st" id="yiyi-123">有关可能的更多详细信息,请参阅<a class="reference internal" href="../using/cmdline.html#cmdoption-W"><code class="xref std std-option docutils literal"><span class="pre">-W</span></code></a>标志。</span></p><p><span class="yiyi-st" id="yiyi-124">要以编程方式执行与<code class="xref std std-option docutils literal"><span class="pre">-Wd</span></code>相同的操作,请使用:</span></p><pre><code class="language-python"><span></span><span class="n">warnings</span><span class="o">.</span><span class="n">simplefilter</span><span class="p">(</span><span class="s1">'default'</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-125">请务必尽快执行此代码。</span><span class="yiyi-st" id="yiyi-126">这防止了注意哪些警告已经引起意外地影响未来警告的处理方式。</span></p><p><span class="yiyi-st" id="yiyi-127">默认情况下忽略某些警告是为了防止用户看到只对开发者感兴趣的警告。</span><span class="yiyi-st" id="yiyi-128">由于您不一定能够控制用户使用何种解释器来运行代码因此可能会在您的发布周期之间发布新版本的Python。</span><span class="yiyi-st" id="yiyi-129">新的解释器版本可能会在您的代码中触发新的警告,这在旧的解释器中不存在。</span><span class="yiyi-st" id="yiyi-130"><a class="reference internal" href="exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal"><span class="pre">DeprecationWarning</span></code></a>您正在使用的模块。</span><span class="yiyi-st" id="yiyi-131">虽然您作为开发人员希望通知您的代码正在使用已弃用的模块,但对用户而言,此信息本质上是噪音,对他们没有任何好处。</span></p><p><span class="yiyi-st" id="yiyi-132">在运行测试时,<a class="reference internal" href="unittest.html#module-unittest" title="unittest: Unit testing framework for Python."><code class="xref py py-mod docutils literal"><span class="pre">unittest</span></code></a>模块也已更新为使用<code class="docutils literal"><span class="pre">'default'</span></code>过滤器。</span></p></div><div class="section" id="available-functions"><h2><span class="yiyi-st" id="yiyi-133">29.5.6. </span><span class="yiyi-st" id="yiyi-134">Available Functions</span></h2><dl class="function"><dt id="warnings.warn"><span class="yiyi-st" id="yiyi-135"> <code class="descclassname">warnings.</code><code class="descname">warn</code><span class="sig-paren">(</span><em>message</em>, <em>category=None</em>, <em>stacklevel=1</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-136">发出警告,或者可能忽略它或引发异常。</span><span class="yiyi-st" id="yiyi-137"><em>类别</em>参数(如果给出)必须是警告类别类(见上文);它默认为<a class="reference internal" href="exceptions.html#UserWarning" title="UserWarning"><code class="xref py py-exc docutils literal"><span class="pre">UserWarning</span></code></a></span><span class="yiyi-st" id="yiyi-138">或者,<em>消息</em>可以是<a class="reference internal" href="exceptions.html#Warning" title="Warning"><code class="xref py py-exc docutils literal"><span class="pre">Warning</span></code></a>实例,在这种情况下,将忽略<em>类别</em>,将使用<code class="docutils literal"><span class="pre">message.__class__</span></code></span><span class="yiyi-st" id="yiyi-139">在这种情况下,消息文本将是<code class="docutils literal"><span class="pre">str(message)</span></code></span><span class="yiyi-st" id="yiyi-140">如果发出的特定警告由警告过滤器更改为错误,则此函数引发异常。</span><span class="yiyi-st" id="yiyi-141"><em>stacklevel</em>参数可以用Python编写的wrapper函数使用如下所示</span></p><pre><code class="language-python"><span></span><span class="k">def</span> <span class="nf">deprecation</span><span class="p">(</span><span class="n">message</span><span class="p">):</span>
<span class="n">warnings</span><span class="o">.</span><span class="n">warn</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="ne">DeprecationWarning</span><span class="p">,</span> <span class="n">stacklevel</span><span class="o">=</span><span class="mi">2</span><span class="p">)</span>
</code></pre><p><span class="yiyi-st" id="yiyi-142">这使得警告引用<code class="xref py py-func docutils literal"><span class="pre">deprecation()</span></code>的调用者,而不是<code class="xref py py-func docutils literal"><span class="pre">deprecation()</span></code>本身的源(因为后者将会违反警告消息的目的) 。</span></p></dd></dl><dl class="function"><dt id="warnings.warn_explicit"><span class="yiyi-st" id="yiyi-143"> <code class="descclassname">warnings.</code><code class="descname">warn_explicit</code><span class="sig-paren">(</span><em>message</em>, <em>category</em>, <em>filename</em>, <em>lineno</em>, <em>module=None</em>, <em>registry=None</em>, <em>module_globals=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-144">这是对<a class="reference internal" href="#warnings.warn" title="warnings.warn"><code class="xref py py-func docutils literal"><span class="pre">warn()</span></code></a>功能的低级接口,显式传递消息,类别,文件名和行号,以及可选的模块名称和注册表(应为<code class="docutils literal"><span class="pre">__warningregistry__</span></code>模块的字典)。</span><span class="yiyi-st" id="yiyi-145">模块名称默认为带有<code class="docutils literal"><span class="pre">.py</span></code> stripped的文件名如果没有传递注册表则永远不会禁止警告。</span><span class="yiyi-st" id="yiyi-146"><em>message</em> must be a string and <em>category</em> a subclass of <a class="reference internal" href="exceptions.html#Warning" title="Warning"><code class="xref py py-exc docutils literal"><span class="pre">Warning</span></code></a> or <em>message</em> may be a <a class="reference internal" href="exceptions.html#Warning" title="Warning"><code class="xref py py-exc docutils literal"><span class="pre">Warning</span></code></a> instance, in which case <em>category</em> will be ignored.</span></p><p><span class="yiyi-st" id="yiyi-147"><em>module_globals</em>(如果提供)应该是发出警告的代码正在使用的全局命名空间。</span><span class="yiyi-st" id="yiyi-148">此参数用于支持在zipfiles或其他非文件系统导入源中找到的模块的源代码</span></p></dd></dl><dl class="function"><dt id="warnings.showwarning"><span class="yiyi-st" id="yiyi-149"> <code class="descclassname">warnings.</code><code class="descname">showwarning</code><span class="sig-paren">(</span><em>message</em>, <em>category</em>, <em>filename</em>, <em>lineno</em>, <em>file=None</em>, <em>line=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-150">向文件写入警告。</span><span class="yiyi-st" id="yiyi-151">默认实现调用<code class="docutils literal"><span class="pre">formatwarningmessage</span> <span class="pre">category</span> <span class="pre">filename</span> <span class="pre">lineno</span> <span class="pre"></span></code>,并将结果字符串写入<em>文件</em>,默认为<code class="docutils literal"><span class="pre">sys.stderr</span></code></span><span class="yiyi-st" id="yiyi-152">您可以通过分配<code class="docutils literal"><span class="pre">warnings.showwarning</span></code>来将此函数替换为任何可调用的函数。</span><span class="yiyi-st" id="yiyi-153"><em></em>是要包括在警告消息中的一行源代码;如果未提供<em></em><a class="reference internal" href="#warnings.showwarning" title="warnings.showwarning"><code class="xref py py-func docutils literal"><span class="pre">showwarning()</span></code></a>将尝试读取由<em>filename</em><em>lineno</em>指定的行。</span></p></dd></dl><dl class="function"><dt id="warnings.formatwarning"><span class="yiyi-st" id="yiyi-154"> <code class="descclassname">warnings.</code><code class="descname">formatwarning</code><span class="sig-paren">(</span><em>message</em>, <em>category</em>, <em>filename</em>, <em>lineno</em>, <em>line=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-155">按标准方式格式化警告。</span><span class="yiyi-st" id="yiyi-156">这将返回一个字符串,它可能包含嵌入的换行符,并以换行符结束。</span><span class="yiyi-st" id="yiyi-157"><em></em>是要包括在警告消息中的一行源代码;如果未提供<em></em>,则<a class="reference internal" href="#warnings.formatwarning" title="warnings.formatwarning"><code class="xref py py-func docutils literal"><span class="pre">formatwarning()</span></code></a>将尝试读取由<em>filename</em><em>lineno</em>指定的行。</span></p></dd></dl><dl class="function"><dt id="warnings.filterwarnings"><span class="yiyi-st" id="yiyi-158"> <code class="descclassname">warnings.</code><code class="descname">filterwarnings</code><span class="sig-paren">(</span><em>action</em>, <em>message=''</em>, <em>category=Warning</em>, <em>module=''</em>, <em>lineno=0</em>, <em>append=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-159"><a class="reference internal" href="#warning-filter"><span>warnings filter specifications</span></a>列表中插入一个条目。</span><span class="yiyi-st" id="yiyi-160">默认情况下,条目插入在前面;如果<em>append</em>为true则在末尾插入。</span><span class="yiyi-st" id="yiyi-161">这会检查参数的类型,编译<em>消息</em><em>模块</em>正则表达式,并将其作为警告过滤器列表中的元组插入。</span><span class="yiyi-st" id="yiyi-162">更靠近列表前面的条目将覆盖列表中后面的条目(如果两者都匹配特定警告)。</span><span class="yiyi-st" id="yiyi-163">省略的参数默认为匹配一切的值。</span></p></dd></dl><dl class="function"><dt id="warnings.simplefilter"><span class="yiyi-st" id="yiyi-164"> <code class="descclassname">warnings.</code><code class="descname">simplefilter</code><span class="sig-paren">(</span><em>action</em>, <em>category=Warning</em>, <em>lineno=0</em>, <em>append=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-165"><a class="reference internal" href="#warning-filter"><span>warnings filter specifications</span></a>列表中插入一个简单的条目。</span><span class="yiyi-st" id="yiyi-166">函数参数的含义是<a class="reference internal" href="#warnings.filterwarnings" title="warnings.filterwarnings"><code class="xref py py-func docutils literal"><span class="pre">filterwarnings()</span></code></a>,但是不需要正则表达式,因为插入的过滤器总是匹配任何模块中的任何消息,只要类别和行号匹配。</span></p></dd></dl><dl class="function"><dt id="warnings.resetwarnings"><span class="yiyi-st" id="yiyi-167"> <code class="descclassname">warnings.</code><code class="descname">resetwarnings</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-168">重置警告过滤器。</span><span class="yiyi-st" id="yiyi-169">这将舍弃之前对<a class="reference internal" href="#warnings.filterwarnings" title="warnings.filterwarnings"><code class="xref py py-func docutils literal"><span class="pre">filterwarnings()</span></code></a>的所有调用(包括<a class="reference internal" href="../using/cmdline.html#cmdoption-W"><code class="xref std std-option docutils literal"><span class="pre">-W</span></code></a>命令行选项和对<a class="reference internal" href="#warnings.simplefilter" title="warnings.simplefilter"><code class="xref py py-func docutils literal"><span class="pre">simplefilter()</span></code></a>的调用)的影响。</span></p></dd></dl></div><div class="section" id="available-context-managers"><h2><span class="yiyi-st" id="yiyi-170">29.5.7. </span><span class="yiyi-st" id="yiyi-171">Available Context Managers</span></h2><dl class="class"><dt id="warnings.catch_warnings"><span class="yiyi-st" id="yiyi-172"> <em class="property">class </em><code class="descclassname">warnings.</code><code class="descname">catch_warnings</code><span class="sig-paren">(</span><em>*</em>, <em>record=False</em>, <em>module=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-173">上下文管理器复制并退出时恢复警告过滤器和<a class="reference internal" href="#warnings.showwarning" title="warnings.showwarning"><code class="xref py py-func docutils literal"><span class="pre">showwarning()</span></code></a>函数。</span><span class="yiyi-st" id="yiyi-174">如果<em>记录</em>参数为<a class="reference internal" href="constants.html#False" title="False"><code class="xref py py-const docutils literal"><span class="pre">False</span></code></a>(默认值),则上下文管理器在条目上返回<a class="reference internal" href="constants.html#None" title="None"><code class="xref py py-class docutils literal"><span class="pre">None</span></code></a></span><span class="yiyi-st" id="yiyi-175">If <em>record</em> is <a class="reference internal" href="constants.html#True" title="True"><code class="xref py py-const docutils literal"><span class="pre">True</span></code></a>, a list is returned that is progressively populated with objects as seen by a custom <a class="reference internal" href="#warnings.showwarning" title="warnings.showwarning"><code class="xref py py-func docutils literal"><span class="pre">showwarning()</span></code></a> function (which also suppresses output to <code class="docutils literal"><span class="pre">sys.stdout</span></code>). </span><span class="yiyi-st" id="yiyi-176">列表中的每个对象都具有与<a class="reference internal" href="#warnings.showwarning" title="warnings.showwarning"><code class="xref py py-func docutils literal"><span class="pre">showwarning()</span></code></a>的参数具有相同名称的属性。</span></p><p><span class="yiyi-st" id="yiyi-177"><em>模块</em>参数使用将使用的模块,而不是在导入其过滤器将受保护的<a class="reference internal" href="#module-warnings" title="warnings: Issue warning messages and control their disposition."><code class="xref py py-mod docutils literal"><span class="pre">warnings</span></code></a>时返回的模块。</span><span class="yiyi-st" id="yiyi-178">此参数主要用于测试<a class="reference internal" href="#module-warnings" title="warnings: Issue warning messages and control their disposition."><code class="xref py py-mod docutils literal"><span class="pre">warnings</span></code></a>模块本身。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-179">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-180"><a class="reference internal" href="#warnings.catch_warnings" title="warnings.catch_warnings"><code class="xref py py-class docutils literal"><span class="pre">catch_warnings</span></code></a>管理器通过替换然后稍后恢复模块的<a class="reference internal" href="#warnings.showwarning" title="warnings.showwarning"><code class="xref py py-func docutils literal"><span class="pre">showwarning()</span></code></a>函数和过滤器规范的内部列表来工作。</span><span class="yiyi-st" id="yiyi-181">这意味着上下文管理器正在修改全局状态,因此不是线程安全的。</span></p></div></dd></dl></div></div></div>