2019-04-08 23:22:26 +08:00

1 line
19 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-code"><h1><span class="yiyi-st" id="yiyi-10">30.1. <a class="reference internal" href="#module-code" title="code: Facilities to implement read-eval-print loops."><code class="xref py py-mod docutils literal"><span class="pre">code</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/code.py">Lib / code.py</a></span></p><p><span class="yiyi-st" id="yiyi-12"><code class="docutils literal"><span class="pre">code</span></code>模块提供了在Python中实现read-eval-print循环的功能。</span><span class="yiyi-st" id="yiyi-13">包括两个类和便利功能,其可以用于构建提供交互式解释器提示的应用。</span></p><dl class="class"><dt id="code.InteractiveInterpreter"><span class="yiyi-st" id="yiyi-14"> <em class="property">class </em><code class="descclassname">code.</code><code class="descname">InteractiveInterpreter</code><span class="sig-paren">(</span><em>locals=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-15">None</span><span class="yiyi-st" id="yiyi-16">可选的<em>locals</em>参数指定将在其中执行代码的字典;默认为新创建的字典,键<code class="docutils literal"><span class="pre">'__name__'</span></code>设置为<code class="docutils literal"><span class="pre">'__console__'</span></code>,键<code class="docutils literal"><span class="pre">'__doc__'</span></code>设置为<code class="docutils literal"><span class="pre">None</span></code></span></p></dd></dl><dl class="class"><dt id="code.InteractiveConsole"><span class="yiyi-st" id="yiyi-17"> <em class="property">class </em><code class="descclassname">code.</code><code class="descname">InteractiveConsole</code><span class="sig-paren">(</span><em>locals=None</em>, <em>filename="&lt;console&gt;"</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-18">None</span><span class="yiyi-st" id="yiyi-19">此类构建在<a class="reference internal" href="#code.InteractiveInterpreter" title="code.InteractiveInterpreter"><code class="xref py py-class docutils literal"><span class="pre">InteractiveInterpreter</span></code></a>上,并使用熟悉的<code class="docutils literal"><span class="pre">sys.ps1</span></code><code class="docutils literal"><span class="pre">sys.ps2</span></code>添加提示,并输入缓冲。</span></p></dd></dl><dl class="function"><dt id="code.interact"><span class="yiyi-st" id="yiyi-20"> <code class="descclassname">code.</code><code class="descname">interact</code><span class="sig-paren">(</span><em>banner=None</em>, <em>readfunc=None</em>, <em>local=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-21">便利功能运行读取 - 打印回路。</span><span class="yiyi-st" id="yiyi-22">这将创建<a class="reference internal" href="#code.InteractiveConsole" title="code.InteractiveConsole"><code class="xref py py-class docutils literal"><span class="pre">InteractiveConsole</span></code></a>的新实例,并将<em>readfunc</em>设置为<a class="reference internal" href="#code.InteractiveConsole.raw_input" title="code.InteractiveConsole.raw_input"><code class="xref py py-meth docutils literal"><span class="pre">InteractiveConsole.raw_input()</span></code></a>方法(如果提供)。</span><span class="yiyi-st" id="yiyi-23">如果提供<em>local</em>,则会传递到<a class="reference internal" href="#code.InteractiveConsole" title="code.InteractiveConsole"><code class="xref py py-class docutils literal"><span class="pre">InteractiveConsole</span></code></a>构造函数,以用作解释器循环的默认命名空间。</span><span class="yiyi-st" id="yiyi-24">然后,实例的<a class="reference internal" href="#code.interact" title="code.interact"><code class="xref py py-meth docutils literal"><span class="pre">interact()</span></code></a>方法将作为横幅广告使用的<em>banner</em>运行(如果提供)。</span><span class="yiyi-st" id="yiyi-25">控制台对象在使用后将被丢弃。</span></p></dd></dl><dl class="function"><dt id="code.compile_command"><span class="yiyi-st" id="yiyi-26"> <code class="descclassname">code.</code><code class="descname">compile_command</code><span class="sig-paren">(</span><em>source</em>, <em>filename="&lt;input&gt;"</em>, <em>symbol="single"</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-27">这个函数对于想要模拟Python的解释器主循环a.k.a.</span><span class="yiyi-st" id="yiyi-28">read-eval-print循环</span><span class="yiyi-st" id="yiyi-29">棘手的部分是确定用户何时输入了可以通过输入更多文本(而不是完整命令或语法错误)完成的不完整命令。</span><span class="yiyi-st" id="yiyi-30">此函数<em>几乎</em>总是做出与真实解释器主循环相同的决定。</span></p><p><span class="yiyi-st" id="yiyi-31"><em></em>是源字符串; <em>filename</em>是从中读取源的可选文件名,默认为<code class="docutils literal"><span class="pre">'&lt;input&gt;'</span></code>;和<em>符号</em>是可选的语法起始符号,应为<code class="docutils literal"><span class="pre">'single'</span></code>(默认值)或<code class="docutils literal"><span class="pre">'eval'</span></code></span></p><p><span class="yiyi-st" id="yiyi-32">如果命令完成,则返回一个代码对象(与<code class="docutils literal"><span class="pre">compilesource</span> <span class="pre">filename</span> <span class="pre">符号)</span></code>和有效; <code class="docutils literal"><span class="pre">None</span></code>如果命令不完整;如果命令包含无效的字面值,则如果命令完成且包含语法错误,则引发<a class="reference internal" href="exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal"><span class="pre">SyntaxError</span></code></a>,或引发<a class="reference internal" href="exceptions.html#OverflowError" title="OverflowError"><code class="xref py py-exc docutils literal"><span class="pre">OverflowError</span></code></a><a class="reference internal" href="exceptions.html#ValueError" title="ValueError"><code class="xref py py-exc docutils literal"><span class="pre">ValueError</span></code></a></span></p></dd></dl><div class="section" id="interactive-interpreter-objects"><h2><span class="yiyi-st" id="yiyi-33">30.1.1. </span><span class="yiyi-st" id="yiyi-34">交互式解释器对象</span></h2><dl class="method"><dt id="code.InteractiveInterpreter.runsource"><span class="yiyi-st" id="yiyi-35"> <code class="descclassname">InteractiveInterpreter.</code><code class="descname">runsource</code><span class="sig-paren">(</span><em>source</em>, <em>filename="&lt;input&gt;"</em>, <em>symbol="single"</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-36">在解释器中编译并运行一些源代码。</span><span class="yiyi-st" id="yiyi-37">参数与<a class="reference internal" href="#code.compile_command" title="code.compile_command"><code class="xref py py-func docutils literal"><span class="pre">compile_command()</span></code></a>相同; <em>filename</em>的默认值为<code class="docutils literal"><span class="pre">'&lt;input&gt;'</span></code><em>符号</em>的默认值为<code class="docutils literal"><span class="pre">'single'</span></code></span><span class="yiyi-st" id="yiyi-38">有几件事情可能发生:</span></p><ul class="simple"><li><span class="yiyi-st" id="yiyi-39">输入不正确; <a class="reference internal" href="#code.compile_command" title="code.compile_command"><code class="xref py py-func docutils literal"><span class="pre">compile_command()</span></code></a>引发了一个异常(<a class="reference internal" href="exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal"><span class="pre">SyntaxError</span></code></a><a class="reference internal" href="exceptions.html#OverflowError" title="OverflowError"><code class="xref py py-exc docutils literal"><span class="pre">OverflowError</span></code></a>)。</span><span class="yiyi-st" id="yiyi-40">将通过调用<a class="reference internal" href="#code.InteractiveInterpreter.showsyntaxerror" title="code.InteractiveInterpreter.showsyntaxerror"><code class="xref py py-meth docutils literal"><span class="pre">showsyntaxerror()</span></code></a>方法打印语法追溯。</span><span class="yiyi-st" id="yiyi-41"><a class="reference internal" href="#code.InteractiveInterpreter.runsource" title="code.InteractiveInterpreter.runsource"><code class="xref py py-meth docutils literal"><span class="pre">runsource()</span></code></a>返回<code class="docutils literal"><span class="pre">False</span></code></span></li><li><span class="yiyi-st" id="yiyi-42">输入不完整,需要更多的输入; <a class="reference internal" href="#code.compile_command" title="code.compile_command"><code class="xref py py-func docutils literal"><span class="pre">compile_command()</span></code></a>返回<code class="docutils literal"><span class="pre">None</span></code></span><span class="yiyi-st" id="yiyi-43"><a class="reference internal" href="#code.InteractiveInterpreter.runsource" title="code.InteractiveInterpreter.runsource"><code class="xref py py-meth docutils literal"><span class="pre">runsource()</span></code></a>返回<code class="docutils literal"><span class="pre">True</span></code></span></li><li><span class="yiyi-st" id="yiyi-44">输入完成; <a class="reference internal" href="#code.compile_command" title="code.compile_command"><code class="xref py py-func docutils literal"><span class="pre">compile_command()</span></code></a>返回了一个代码对象。</span><span class="yiyi-st" id="yiyi-45">通过调用<a class="reference internal" href="#code.InteractiveInterpreter.runcode" title="code.InteractiveInterpreter.runcode"><code class="xref py py-meth docutils literal"><span class="pre">runcode()</span></code></a>(它还处理运行时异常,除了<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-46"><a class="reference internal" href="#code.InteractiveInterpreter.runsource" title="code.InteractiveInterpreter.runsource"><code class="xref py py-meth docutils literal"><span class="pre">runsource()</span></code></a>返回<code class="docutils literal"><span class="pre">False</span></code></span></li></ul><p><span class="yiyi-st" id="yiyi-47">返回值可用于决定是使用<code class="docutils literal"><span class="pre">sys.ps1</span></code>还是<code class="docutils literal"><span class="pre">sys.ps2</span></code>提示下一行。</span></p></dd></dl><dl class="method"><dt id="code.InteractiveInterpreter.runcode"><span class="yiyi-st" id="yiyi-48"> <code class="descclassname">InteractiveInterpreter.</code><code class="descname">runcode</code><span class="sig-paren">(</span><em>code</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-49">执行代码对象。</span><span class="yiyi-st" id="yiyi-50">发生异常时,调用<a class="reference internal" href="#code.InteractiveInterpreter.showtraceback" title="code.InteractiveInterpreter.showtraceback"><code class="xref py py-meth docutils literal"><span class="pre">showtraceback()</span></code></a>以显示跟踪。</span><span class="yiyi-st" id="yiyi-51">除了<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></p><p><span class="yiyi-st" id="yiyi-52">关于<a class="reference internal" href="exceptions.html#KeyboardInterrupt" title="KeyboardInterrupt"><code class="xref py py-exc docutils literal"><span class="pre">KeyboardInterrupt</span></code></a>的注释:此异常可能会在此代码的其他位置发生,并且可能不会总是被捕获。</span><span class="yiyi-st" id="yiyi-53">调用者应该准备处理它。</span></p></dd></dl><dl class="method"><dt id="code.InteractiveInterpreter.showsyntaxerror"><span class="yiyi-st" id="yiyi-54"> <code class="descclassname">InteractiveInterpreter.</code><code class="descname">showsyntaxerror</code><span class="sig-paren">(</span><em>filename=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-55">显示刚刚发生的语法错误。</span><span class="yiyi-st" id="yiyi-56">这不显示堆栈跟踪,因为没有语法错误。</span><span class="yiyi-st" id="yiyi-57">如果给出了<em>filename</em>它被填充到异常而不是由Python的解析器提供的默认文件名因为它从字符串读取时总是使用<code class="docutils literal"><span class="pre">'&lt;string&gt;'</span></code></span><span class="yiyi-st" id="yiyi-58">输出由<a class="reference internal" href="#code.InteractiveInterpreter.write" title="code.InteractiveInterpreter.write"><code class="xref py py-meth docutils literal"><span class="pre">write()</span></code></a>方法写入。</span></p></dd></dl><dl class="method"><dt id="code.InteractiveInterpreter.showtraceback"><span class="yiyi-st" id="yiyi-59"> <code class="descclassname">InteractiveInterpreter.</code><code class="descname">showtraceback</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-60">显示刚刚发生的异常。</span><span class="yiyi-st" id="yiyi-61">我们删除第一个堆栈项,因为它在解释器对象实现中。</span><span class="yiyi-st" id="yiyi-62">输出由<a class="reference internal" href="#code.InteractiveInterpreter.write" title="code.InteractiveInterpreter.write"><code class="xref py py-meth docutils literal"><span class="pre">write()</span></code></a>方法写入。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-63"><span class="versionmodified">在版本3.5中更改:</span>显示完全链式跟踪,而不是仅显示主要跟踪。</span></p></div></dd></dl><dl class="method"><dt id="code.InteractiveInterpreter.write"><span class="yiyi-st" id="yiyi-64"> <code class="descclassname">InteractiveInterpreter.</code><code class="descname">write</code><span class="sig-paren">(</span><em>data</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-65">将一个字符串写入标准错误流(<code class="docutils literal"><span class="pre">sys.stderr</span></code>)。</span><span class="yiyi-st" id="yiyi-66">派生类应该覆盖此,以根据需要提供适当的输出处理。</span></p></dd></dl></div><div class="section" id="interactive-console-objects"><h2><span class="yiyi-st" id="yiyi-67">30.1.2. </span><span class="yiyi-st" id="yiyi-68">交互式控制台对象</span></h2><p><span class="yiyi-st" id="yiyi-69"><a class="reference internal" href="#code.InteractiveConsole" title="code.InteractiveConsole"><code class="xref py py-class docutils literal"><span class="pre">InteractiveConsole</span></code></a>类是<a class="reference internal" href="#code.InteractiveInterpreter" title="code.InteractiveInterpreter"><code class="xref py py-class docutils literal"><span class="pre">InteractiveInterpreter</span></code></a>的子类,因此提供了解释器对象的所有方法以及以下添加项。</span></p><dl class="method"><dt id="code.InteractiveConsole.interact"><span class="yiyi-st" id="yiyi-70"> <code class="descclassname">InteractiveConsole.</code><code class="descname">interact</code><span class="sig-paren">(</span><em>banner=None</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-71">密切地模拟交互式Python控制台。</span><span class="yiyi-st" id="yiyi-72">可选的<em>横幅</em>参数指定在首次交互之前打印的横幅默认情况下它打印一个类似于标准Python解释器打印的横幅后面是括号中的控制台对象的类名以免混淆到真正的解释器 - 因为它非常接近!</span><span class="yiyi-st" id="yiyi-73">)。</span></p><div class="versionchanged"><p><span class="yiyi-st" id="yiyi-74"><span class="versionmodified">在版本3.4中更改:</span>要禁止打印任何横幅,请传递一个空字符串。</span></p></div></dd></dl><dl class="method"><dt id="code.InteractiveConsole.push"><span class="yiyi-st" id="yiyi-75"> <code class="descclassname">InteractiveConsole.</code><code class="descname">push</code><span class="sig-paren">(</span><em>line</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-76">将一行源文本推送到解释器。</span><span class="yiyi-st" id="yiyi-77">该行不应该有一个尾随换行符;它可能有内部换行符。</span><span class="yiyi-st" id="yiyi-78">该行被附加到缓冲区,并且解释器的<code class="xref py py-meth docutils literal"><span class="pre">runsource()</span></code>方法以缓冲区的连接内容作为源来调用。</span><span class="yiyi-st" id="yiyi-79">如果这表示命令已执行或无效,则缓冲区复位;否则,命令不完整,并且缓冲区在添加行之后保留。</span><span class="yiyi-st" id="yiyi-80">如果需要更多输入,返回值为<code class="docutils literal"><span class="pre">True</span></code><code class="docutils literal"><span class="pre">False</span></code>如果以某种方式处理该行(这与<code class="xref py py-meth docutils literal"><span class="pre">runsource()</span></code></span></p></dd></dl><dl class="method"><dt id="code.InteractiveConsole.resetbuffer"><span class="yiyi-st" id="yiyi-81"> <code class="descclassname">InteractiveConsole.</code><code class="descname">resetbuffer</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-82">从输入缓冲区中删除任何未处理的源文本。</span></p></dd></dl><dl class="method"><dt id="code.InteractiveConsole.raw_input"><span class="yiyi-st" id="yiyi-83"> <code class="descclassname">InteractiveConsole.</code><code class="descname">raw_input</code><span class="sig-paren">(</span><em>prompt=""</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-84">写一个提示并读一行。</span><span class="yiyi-st" id="yiyi-85">返回的行不包括尾随换行符。</span><span class="yiyi-st" id="yiyi-86">当用户输入EOF键序列时会出现<a class="reference internal" href="exceptions.html#EOFError" title="EOFError"><code class="xref py py-exc docutils literal"><span class="pre">EOFError</span></code></a></span><span class="yiyi-st" id="yiyi-87">基本实现从<code class="docutils literal"><span class="pre">sys.stdin</span></code>;子类可以用不同的实现来代替。</span></p></dd></dl></div></div></div>