mirror of
https://github.com/fofolee/uTools-Manuals.git
synced 2025-06-09 15:34:05 +08:00
20 lines
33 KiB
HTML
20 lines
33 KiB
HTML
<div class="body" role="main"><div class="section" id="module-parser"><h1><span class="yiyi-st" id="yiyi-10">32.1. <a class="reference internal" href="#module-parser" title="parser: Access parse trees for Python source code."><code class="xref py py-mod docutils literal"><span class="pre">parser</span></code></a> - 访问Python解析树</span></h1><p><span class="yiyi-st" id="yiyi-11"><a class="reference internal" href="#module-parser" title="parser: Access parse trees for Python source code."><code class="xref py py-mod docutils literal"><span class="pre">parser</span></code></a>模块提供了一个到Python的内部解析器和字节码编译器的接口。</span><span class="yiyi-st" id="yiyi-12">此接口的主要目的是允许Python代码编辑Python表达式的分析树,并从中创建可执行代码。</span><span class="yiyi-st" id="yiyi-13">这比尝试将任意Python代码片段解析和修改为字符串更好,因为解析是以与形成应用程序的代码相同的方式执行的。</span><span class="yiyi-st" id="yiyi-14">它也更快。</span></p><div class="admonition note"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-15">注意</span></p><p class="last"><span class="yiyi-st" id="yiyi-16">从Python 2.5开始,使用<a class="reference internal" href="ast.html#module-ast" title="ast: Abstract Syntax Tree classes and manipulation."><code class="xref py py-mod docutils literal"><span class="pre">ast</span></code></a>模块在抽象语法树(AST)生成和编译阶段中切入更为方便。</span></p></div><p><span class="yiyi-st" id="yiyi-17">有一些要注意的事情,这个模块对于使用创建的数据结构很重要。</span><span class="yiyi-st" id="yiyi-18">这不是编辑Python代码的解析树的教程,但是提供了使用<a class="reference internal" href="#module-parser" title="parser: Access parse trees for Python source code."><code class="xref py py-mod docutils literal"><span class="pre">parser</span></code></a>模块的一些示例。</span></p><p><span class="yiyi-st" id="yiyi-19">最重要的是,需要很好地理解由内部解析器处理的Python语法。</span><span class="yiyi-st" id="yiyi-20">有关语言语法的完整信息,请参阅<a class="reference internal" href="../reference/index.html#reference-index"><span>The Python Language Reference</span></a>。</span><span class="yiyi-st" id="yiyi-21">解析器本身是从标准Python分发中的文件<code class="file docutils literal"><span class="pre">Grammar/Grammar</span></code>中定义的语法规范创建的。</span><span class="yiyi-st" id="yiyi-22">由此模块创建的ST对象中存储的解析树是由<a class="reference internal" href="#parser.expr" title="parser.expr"><code class="xref py py-func docutils literal"><span class="pre">expr()</span></code></a>或<a class="reference internal" href="#parser.suite" title="parser.suite"><code class="xref py py-func docutils literal"><span class="pre">suite()</span></code></a>函数创建时内部解析器的实际输出,如下所述。</span><span class="yiyi-st" id="yiyi-23">由<a class="reference internal" href="#parser.sequence2st" title="parser.sequence2st"><code class="xref py py-func docutils literal"><span class="pre">sequence2st()</span></code></a>创建的ST对象忠实地模拟这些结构。</span><span class="yiyi-st" id="yiyi-24">请注意,被认为“正确”的序列的值将随着Python的一个版本而变化,因为语言的正式语法被修改。</span><span class="yiyi-st" id="yiyi-25">但是,将代码从一个Python版本传输到另一个作为源文本将始终允许在目标版本中创建正确的解析树,唯一的限制是迁移到旧版本的解释器将不支持更多的最近的语言结构。</span><span class="yiyi-st" id="yiyi-26">解析树通常不是从一个版本到另一个版本是兼容的,而源代码总是向前兼容的。</span></p><p><span class="yiyi-st" id="yiyi-27"><a class="reference internal" href="#parser.st2list" title="parser.st2list"><code class="xref py py-func docutils literal"><span class="pre">st2list()</span></code></a>或<a class="reference internal" href="#parser.st2tuple" title="parser.st2tuple"><code class="xref py py-func docutils literal"><span class="pre">st2tuple()</span></code></a>返回的序列的每个元素都有一个简单的形式。</span><span class="yiyi-st" id="yiyi-28">表示语法中的非终端元素的序列总是具有大于1的长度。</span><span class="yiyi-st" id="yiyi-29">第一个元素是标识语法中的生产的整数。</span><span class="yiyi-st" id="yiyi-30">这些整数在C头文件<code class="file docutils literal"><span class="pre">Include/graminit.h</span></code>和Python模块<a class="reference internal" href="symbol.html#module-symbol" title="symbol: Constants representing internal nodes of the parse tree."><code class="xref py py-mod docutils literal"><span class="pre">symbol</span></code></a>中给出符号名称。</span><span class="yiyi-st" id="yiyi-31">序列的每个附加元素表示在输入字符串中识别的生产的组件:这些总是具有与父相同形式的序列。</span><span class="yiyi-st" id="yiyi-32">应该注意的这种结构的一个重要方面是用于标识父节点类型的关键字,例如<code class="xref py py-const docutils literal"><span class="pre">if_stmt</span></code>中的关键字<a class="reference internal" href="../reference/compound_stmts.html#if"><code class="xref std std-keyword docutils literal"><span class="pre">if</span></code></a>被包括在节点树中无需任何特殊处理。</span><span class="yiyi-st" id="yiyi-33">例如,<a class="reference internal" href="../reference/compound_stmts.html#if"><code class="xref std std-keyword docutils literal"><span class="pre">if</span></code></a>关键字由元组<code class="docutils literal"><span class="pre">(1,</span> <span class="pre">'if')</span></code>表示,其中<code class="docutils literal"><span class="pre">1</span></code>是与所有<code class="xref py py-const docutils literal"><span class="pre">NAME</span></code>令牌相关联的数值,包括用户定义的变量和函数名称。</span><span class="yiyi-st" id="yiyi-34">在请求线路号信息时返回的备选形式中,相同的令牌可以表示为<code class="docutils literal"><span class="pre">(1,</span> <span class="pre">'if',</span> <span class="pre">12) t3></span></code>,其中<code class="docutils literal"><span class="pre">12</span></code>表示找到终端符号的行号。</span></p><p><span class="yiyi-st" id="yiyi-35">终端元素以非常相同的方式表示,但没有任何子元素,并且添加了被识别的源文本。</span><span class="yiyi-st" id="yiyi-36">上面的<a class="reference internal" href="../reference/compound_stmts.html#if"><code class="xref std std-keyword docutils literal"><span class="pre">if</span></code></a>关键字的示例是有代表性的。</span><span class="yiyi-st" id="yiyi-37">各种类型的终端符号在C头文件<code class="file docutils literal"><span class="pre">Include/token.h</span></code>和Python模块<a class="reference internal" href="token.html#module-token" title="token: Constants representing terminal nodes of the parse tree."><code class="xref py py-mod docutils literal"><span class="pre">token</span></code></a>中定义。</span></p><p><span class="yiyi-st" id="yiyi-38">ST对象不需要支持该模块的功能,但是被提供用于三个目的:允许应用分摊处理复杂解析树的成本,以提供解析树表示,其与Python相比节省存储器空间列表或元组表示,并且易于在C中创建操纵解析树的附加模块。</span><span class="yiyi-st" id="yiyi-39">可以在Python中创建一个简单的“包装器”类,以隐藏ST对象的使用。</span></p><p><span class="yiyi-st" id="yiyi-40"><a class="reference internal" href="#module-parser" title="parser: Access parse trees for Python source code."><code class="xref py py-mod docutils literal"><span class="pre">parser</span></code></a>模块定义了几个不同目的的函数。</span><span class="yiyi-st" id="yiyi-41">最重要的目的是创建ST对象并将ST对象转换为其他表示形式,例如解析树和编译代码对象,但也有用于查询由ST对象表示的解析树类型的函数。</span></p><div class="admonition seealso"><p class="first admonition-title"><span class="yiyi-st" id="yiyi-42">也可以看看</span></p><dl class="last docutils"><dt><span class="yiyi-st" id="yiyi-43">模块<a class="reference internal" href="symbol.html#module-symbol" title="symbol: Constants representing internal nodes of the parse tree."><code class="xref py py-mod docutils literal"><span class="pre">symbol</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-44">有用的常数表示解析树的内部节点。</span></dd><dt><span class="yiyi-st" id="yiyi-45">模块<a class="reference internal" href="token.html#module-token" title="token: Constants representing terminal nodes of the parse tree."><code class="xref py py-mod docutils literal"><span class="pre">token</span></code></a></span></dt><dd><span class="yiyi-st" id="yiyi-46">有用的常数表示解析树的叶节点和用于测试节点值的函数。</span></dd></dl></div><div class="section" id="creating-st-objects"><h2><span class="yiyi-st" id="yiyi-47">32.1.1. </span><span class="yiyi-st" id="yiyi-48">Creating ST Objects</span></h2><p><span class="yiyi-st" id="yiyi-49">ST对象可以从源代码或从解析树创建。</span><span class="yiyi-st" id="yiyi-50">当从源创建ST对象时,使用不同的函数创建<code class="docutils literal"><span class="pre">'eval'</span></code>和<code class="docutils literal"><span class="pre">'exec'</span></code>表单。</span></p><dl class="function"><dt id="parser.expr"><span class="yiyi-st" id="yiyi-51"> <code class="descclassname">parser.</code><code class="descname">expr</code><span class="sig-paren">(</span><em>source</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-52"><a class="reference internal" href="#parser.expr" title="parser.expr"><code class="xref py py-func docutils literal"><span class="pre">expr()</span></code></a>函数解析参数<em>source</em>,就像它是<code class="docutils literal"><span class="pre">compile(source,</span> <span class="pre">'file)的输入。 py',</span> <span class="pre">'eval')</span></code>。</span><span class="yiyi-st" id="yiyi-53">如果解析成功,将创建一个ST对象来保存内部解析树表示,否则会产生一个适当的异常。</span></p></dd></dl><dl class="function"><dt id="parser.suite"><span class="yiyi-st" id="yiyi-54"> <code class="descclassname">parser.</code><code class="descname">suite</code><span class="sig-paren">(</span><em>source</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-55"><a class="reference internal" href="#parser.suite" title="parser.suite"><code class="xref py py-func docutils literal"><span class="pre">suite()</span></code></a>函数解析参数<em>source</em>,就像它是<code class="docutils literal"><span class="pre">compile(source,</span> <span class="pre">'file)的输入。 py',</span> <span class="pre">'exec')</span></code>。</span><span class="yiyi-st" id="yiyi-56">如果解析成功,将创建一个ST对象来保存内部解析树表示,否则会产生一个适当的异常。</span></p></dd></dl><dl class="function"><dt id="parser.sequence2st"><span class="yiyi-st" id="yiyi-57"> <code class="descclassname">parser.</code><code class="descname">sequence2st</code><span class="sig-paren">(</span><em>sequence</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-58">此函数接受表示为序列的解析树,并在可能的情况下构建内部表示。</span><span class="yiyi-st" id="yiyi-59">如果它可以验证树符合Python语法,并且所有节点都是Python主机版本中的有效节点类型,则从内部表示创建ST对象并将其返回给调用。</span><span class="yiyi-st" id="yiyi-60">如果创建内部表示时出现问题,或者无法验证树,则会引发<a class="reference internal" href="#parser.ParserError" title="parser.ParserError"><code class="xref py py-exc docutils literal"><span class="pre">ParserError</span></code></a>异常。</span><span class="yiyi-st" id="yiyi-61">以这种方式创建的ST对象不应被假定为正确编译;当ST对象传递给<a class="reference internal" href="#parser.compilest" title="parser.compilest"><code class="xref py py-func docutils literal"><span class="pre">compilest()</span></code></a>时,编译引发的正常异常可能仍然启动。</span><span class="yiyi-st" id="yiyi-62">这可能指示与语法无关的问题(例如<a class="reference internal" href="exceptions.html#MemoryError" title="MemoryError"><code class="xref py py-exc docutils literal"><span class="pre">MemoryError</span></code></a>异常),但也可能是由于诸如解析<code class="docutils literal"><span class="pre">del</span> <span class="pre">f(0)</span></code>,它转义了Python解析器,但被字节码编译器检查。</span></p><p><span class="yiyi-st" id="yiyi-63">表示终端令牌的序列可以表示为<code class="docutils literal"><span class="pre">(1,</span> <span class="pre">'name')</span></code>形式的两个元素列表或三元素列表形式为<code class="docutils literal"><span class="pre">(1,</span> <span class="pre">'name',</span> <span class="pre">56)</span></code></span><span class="yiyi-st" id="yiyi-64">如果存在第三个元素,则假定它是一个有效的行号。</span><span class="yiyi-st" id="yiyi-65">可以为输入树中的终端符号的任何子集指定行号。</span></p></dd></dl><dl class="function"><dt id="parser.tuple2st"><span class="yiyi-st" id="yiyi-66"> <code class="descclassname">parser.</code><code class="descname">tuple2st</code><span class="sig-paren">(</span><em>sequence</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-67">这与<a class="reference internal" href="#parser.sequence2st" title="parser.sequence2st"><code class="xref py py-func docutils literal"><span class="pre">sequence2st()</span></code></a>具有相同的功能。</span><span class="yiyi-st" id="yiyi-68">保留此入口点以实现向后兼容性。</span></p></dd></dl></div><div class="section" id="converting-st-objects"><h2><span class="yiyi-st" id="yiyi-69">32.1.2. </span><span class="yiyi-st" id="yiyi-70">Converting ST Objects</span></h2><p><span class="yiyi-st" id="yiyi-71">ST对象,无论用于创建它们的输入如何,都可以被转换为表示为列表或元组树的分析树,或者可以被编译为可执行代码对象。</span><span class="yiyi-st" id="yiyi-72">可以使用或不使用行编号信息来提取解析树。</span></p><dl class="function"><dt id="parser.st2list"><span class="yiyi-st" id="yiyi-73"> <code class="descclassname">parser.</code><code class="descname">st2list</code><span class="sig-paren">(</span><em>st</em>, <em>line_info=False</em>, <em>col_info=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-74">此函数在<em>st</em>中接受来自调用者的ST对象,并返回表示等效解析树的Python列表。</span><span class="yiyi-st" id="yiyi-75">所得到的列表表示可以用于检查或以列表形式创建新的解析树。</span><span class="yiyi-st" id="yiyi-76">只要存储器可用于构建列表表示,此函数不会失败。</span><span class="yiyi-st" id="yiyi-77">如果解析树仅用于检查,则应使用<a class="reference internal" href="#parser.st2tuple" title="parser.st2tuple"><code class="xref py py-func docutils literal"><span class="pre">st2tuple()</span></code></a>来减少内存消耗和碎片。</span><span class="yiyi-st" id="yiyi-78">当需要列表表示时,此函数显着快于检索元组表示并将其转换为嵌套列表。</span></p><p><span class="yiyi-st" id="yiyi-79">如果<em>line_info</em>为真,则对于所有终端令牌将包括行号信息作为表示令牌的列表的第三元素。</span><span class="yiyi-st" id="yiyi-80">请注意,提供的行号指定令牌<em>结束的行</em>。</span><span class="yiyi-st" id="yiyi-81">如果标志为假或省略,则省略此信息。</span></p></dd></dl><dl class="function"><dt id="parser.st2tuple"><span class="yiyi-st" id="yiyi-82"> <code class="descclassname">parser.</code><code class="descname">st2tuple</code><span class="sig-paren">(</span><em>st</em>, <em>line_info=False</em>, <em>col_info=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-83">此函数在<em>st</em>中接受来自调用者的ST对象,并返回表示等效解析树的Python元组。</span><span class="yiyi-st" id="yiyi-84">除了返回元组而不是列表,此函数与<a class="reference internal" href="#parser.st2list" title="parser.st2list"><code class="xref py py-func docutils literal"><span class="pre">st2list()</span></code></a>相同。</span></p><p><span class="yiyi-st" id="yiyi-85">如果<em>line_info</em>为真,则对于所有终端令牌将包括行号信息作为表示令牌的列表的第三元素。</span><span class="yiyi-st" id="yiyi-86">如果标志为假或省略,则省略此信息。</span></p></dd></dl><dl class="function"><dt id="parser.compilest"><span class="yiyi-st" id="yiyi-87"> <code class="descclassname">parser.</code><code class="descname">compilest</code><span class="sig-paren">(</span><em>st</em>, <em>filename='<syntax-tree>'</em><span class="sig-paren">)</span></span></dt><dd><p id="index-1"><span class="yiyi-st" id="yiyi-88">Python字节编译器可以在ST对象上调用以产生代码对象,这些对象可以用作调用内建<a class="reference internal" href="functions.html#exec" title="exec"><code class="xref py py-func docutils literal"><span class="pre">exec()</span></code></a>或<a class="reference internal" href="functions.html#eval" title="eval"><code class="xref py py-func docutils literal"><span class="pre">eval()</span></code></a>函数的一部分。</span><span class="yiyi-st" id="yiyi-89">此函数提供了编译器的接口,使用由<em>filename</em>参数指定的源文件名将内部解析树从<em>st</em>传递到解析器。</span><span class="yiyi-st" id="yiyi-90">为<em>filename</em>提供的默认值表示源是ST对象。</span></p><p><span class="yiyi-st" id="yiyi-91">编译ST对象可能会导致与编译相关的异常;示例将是由<code class="docutils literal"><span class="pre">del</span> <span class="pre">f(0)</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>:此语句被考虑在Python的正式语法内的法律,但不是一个法律语言结构。</span><span class="yiyi-st" id="yiyi-92">为此条件引发的<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>实际上是由Python字节编译器正常生成的,这就是为什么此时可由<a class="reference internal" href="#module-parser" title="parser: Access parse trees for Python source code."><code class="xref py py-mod docutils literal"><span class="pre">parser</span></code></a>模块引发的原因。</span><span class="yiyi-st" id="yiyi-93">编译失败的大多数原因可以通过检查解析树以编程方式诊断。</span></p></dd></dl></div><div class="section" id="queries-on-st-objects"><h2><span class="yiyi-st" id="yiyi-94">32.1.3. </span><span class="yiyi-st" id="yiyi-95">Queries on ST Objects</span></h2><p><span class="yiyi-st" id="yiyi-96">提供了两个功能,其允许应用程序确定ST是否被创建为表达式或套件。</span><span class="yiyi-st" id="yiyi-97">这些函数都不能用于确定是否通过<a class="reference internal" href="#parser.expr" title="parser.expr"><code class="xref py py-func docutils literal"><span class="pre">expr()</span></code></a>或<a class="reference internal" href="#parser.suite" title="parser.suite"><code class="xref py py-func docutils literal"><span class="pre">suite()</span></code></a>从源代码创建ST,或者通过<a class="reference internal" href="#parser.sequence2st" title="parser.sequence2st"><code class="xref py py-func docutils literal"><span class="pre">sequence2st()</span></code></a>。</span></p><dl class="function"><dt id="parser.isexpr"><span class="yiyi-st" id="yiyi-98"> <code class="descclassname">parser.</code><code class="descname">isexpr</code><span class="sig-paren">(</span><em>st</em><span class="sig-paren">)</span></span></dt><dd><p id="index-2"><span class="yiyi-st" id="yiyi-99">当<em>st</em>表示<code class="docutils literal"><span class="pre">'eval'</span></code>形式时,此函数返回true,否则返回false。</span><span class="yiyi-st" id="yiyi-100">这是有用的,因为代码对象通常不能使用现有的内建函数查询此信息。</span><span class="yiyi-st" id="yiyi-101">注意,由<a class="reference internal" href="#parser.compilest" title="parser.compilest"><code class="xref py py-func docutils literal"><span class="pre">compilest()</span></code></a>创建的代码对象不能像这样查询,并且与内建<a class="reference internal" href="functions.html#compile" title="compile"><code class="xref py py-func docutils literal"><span class="pre">compile()</span></code></a>函数创建的对象完全相同。</span></p></dd></dl><dl class="function"><dt id="parser.issuite"><span class="yiyi-st" id="yiyi-102"> <code class="descclassname">parser.</code><code class="descname">issuite</code><span class="sig-paren">(</span><em>st</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-103">此函数镜像<a class="reference internal" href="#parser.isexpr" title="parser.isexpr"><code class="xref py py-func docutils literal"><span class="pre">isexpr()</span></code></a>,因为它报告ST对象是否表示<code class="docutils literal"><span class="pre">'exec'</span></code>形式,通常称为“套件”。此函数等效于<code class="docutils literal"><span class="pre">而不是</span> <span class="pre">isexpr(st)</span></code>,因为将来可能支持其他句法片段。</span></p></dd></dl></div><div class="section" id="exceptions-and-error-handling"><h2><span class="yiyi-st" id="yiyi-104">32.1.4. </span><span class="yiyi-st" id="yiyi-105">Exceptions and Error Handling</span></h2><p><span class="yiyi-st" id="yiyi-106">解析器模块定义单个异常,但也可能传递来自Python运行时环境的其他部分的其他内建异常。</span><span class="yiyi-st" id="yiyi-107">有关可以引发的异常的信息,请参阅每个函数。</span></p><dl class="exception"><dt id="parser.ParserError"><span class="yiyi-st" id="yiyi-108"> <em class="property">exception </em><code class="descclassname">parser.</code><code class="descname">ParserError</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-109">在解析器模块中发生故障时引发异常。</span><span class="yiyi-st" id="yiyi-110">这通常用于验证失败,而不是在正常解析期间产生的内建<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>。</span><span class="yiyi-st" id="yiyi-111">异常参数是描述失败原因的字符串或包含导致传递给<a class="reference internal" href="#parser.sequence2st" title="parser.sequence2st"><code class="xref py py-func docutils literal"><span class="pre">sequence2st()</span></code></a>的解析树失败的序列的元组和一个解释字符串。</span><span class="yiyi-st" id="yiyi-112">调用<a class="reference internal" href="#parser.sequence2st" title="parser.sequence2st"><code class="xref py py-func docutils literal"><span class="pre">sequence2st()</span></code></a>需要能够处理任何类型的异常,而对模块中其他函数的调用只需要知道简单的字符串值。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-113">注意,函数<a class="reference internal" href="#parser.compilest" title="parser.compilest"><code class="xref py py-func docutils literal"><span class="pre">compilest()</span></code></a>,<a class="reference internal" href="#parser.expr" title="parser.expr"><code class="xref py py-func docutils literal"><span class="pre">expr()</span></code></a>和<a class="reference internal" href="#parser.suite" title="parser.suite"><code class="xref py py-func docutils literal"><span class="pre">suite()</span></code></a>可能引发通常由解析和编译过程引发的异常。</span><span class="yiyi-st" id="yiyi-114">这些包括内置异常<a class="reference internal" href="exceptions.html#MemoryError" title="MemoryError"><code class="xref py py-exc docutils literal"><span class="pre">MemoryError</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#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#SystemError" title="SystemError"><code class="xref py py-exc docutils literal"><span class="pre">SystemError</span></code></a>。</span><span class="yiyi-st" id="yiyi-115">在这些情况下,这些例外具有通常与它们相关联的所有含义。</span><span class="yiyi-st" id="yiyi-116">有关详细信息,请参阅各功能的说明。</span></p></div><div class="section" id="st-objects"><h2><span class="yiyi-st" id="yiyi-117">32.1.5. </span><span class="yiyi-st" id="yiyi-118">ST Objects</span></h2><p><span class="yiyi-st" id="yiyi-119">ST对象之间支持有序和等式比较。</span><span class="yiyi-st" id="yiyi-120">还支持使用ST对象(使用<a class="reference internal" href="pickle.html#module-pickle" title="pickle: Convert Python objects to streams of bytes and back."><code class="xref py py-mod docutils literal"><span class="pre">pickle</span></code></a>模块)。</span></p><dl class="data"><dt id="parser.STType"><span class="yiyi-st" id="yiyi-121"> <code class="descclassname">parser.</code><code class="descname">STType</code></span></dt><dd><p><span class="yiyi-st" id="yiyi-122">由<a class="reference internal" href="#parser.expr" title="parser.expr"><code class="xref py py-func docutils literal"><span class="pre">expr()</span></code></a>,<a class="reference internal" href="#parser.suite" title="parser.suite"><code class="xref py py-func docutils literal"><span class="pre">suite()</span></code></a>和<a class="reference internal" href="#parser.sequence2st" title="parser.sequence2st"><code class="xref py py-func docutils literal"><span class="pre">sequence2st()</span></code></a>返回的对象类型。</span></p></dd></dl><p><span class="yiyi-st" id="yiyi-123">ST对象有以下方法:</span></p><dl class="method"><dt id="parser.ST.compile"><span class="yiyi-st" id="yiyi-124"> <code class="descclassname">ST.</code><code class="descname">compile</code><span class="sig-paren">(</span><em>filename='<syntax-tree>'</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-125">与<code class="docutils literal"><span class="pre">compilest(st,</span> <span class="pre">filename)</span></code>相同。</span></p></dd></dl><dl class="method"><dt id="parser.ST.isexpr"><span class="yiyi-st" id="yiyi-126"> <code class="descclassname">ST.</code><code class="descname">isexpr</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-127">与<code class="docutils literal"><span class="pre">isexpr(st)</span></code>相同。</span></p></dd></dl><dl class="method"><dt id="parser.ST.issuite"><span class="yiyi-st" id="yiyi-128"> <code class="descclassname">ST.</code><code class="descname">issuite</code><span class="sig-paren">(</span><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-129">与<code class="docutils literal"><span class="pre">issuite(st)</span></code>相同。</span></p></dd></dl><dl class="method"><dt id="parser.ST.tolist"><span class="yiyi-st" id="yiyi-130"> <code class="descclassname">ST.</code><code class="descname">tolist</code><span class="sig-paren">(</span><em>line_info=False</em>, <em>col_info=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-131">与<code class="docutils literal"><span class="pre">st2list(st,</span> <span class="pre">line_info,</span> <span class="pre">col_info)</span></code>相同。</span></p></dd></dl><dl class="method"><dt id="parser.ST.totuple"><span class="yiyi-st" id="yiyi-132"> <code class="descclassname">ST.</code><code class="descname">totuple</code><span class="sig-paren">(</span><em>line_info=False</em>, <em>col_info=False</em><span class="sig-paren">)</span></span></dt><dd><p><span class="yiyi-st" id="yiyi-133">与<code class="docutils literal"><span class="pre">st2tuple(st,</span> <span class="pre">line_info,</span> <span class="pre">col_info)</span></code>相同。</span></p></dd></dl></div><div class="section" id="example-emulation-of-compile"><h2><span class="yiyi-st" id="yiyi-134">32.1.6. </span><span class="yiyi-st" id="yiyi-135">Example: Emulation of <a class="reference internal" href="functions.html#compile" title="compile"><code class="xref py py-func docutils literal"><span class="pre">compile()</span></code></a></span></h2><p><span class="yiyi-st" id="yiyi-136">虽然许多有用的操作可能发生在解析和字节码生成之间,但最简单的操作是不做任何事。</span><span class="yiyi-st" id="yiyi-137">为此,使用<a class="reference internal" href="#module-parser" title="parser: Access parse trees for Python source code."><code class="xref py py-mod docutils literal"><span class="pre">parser</span></code></a>模块产生中间数据结构相当于该代码</span></p><div class="highlight-python3"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="n">code</span> <span class="o">=</span> <span class="nb">compile</span><span class="p">(</span><span class="s1">'a + 5'</span><span class="p">,</span> <span class="s1">'file.py'</span><span class="p">,</span> <span class="s1">'eval'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">a</span> <span class="o">=</span> <span class="mi">5</span>
|
||
<span class="gp">>>> </span><span class="nb">eval</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
|
||
<span class="go">10</span>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-138">使用<a class="reference internal" href="#module-parser" title="parser: Access parse trees for Python source code."><code class="xref py py-mod docutils literal"><span class="pre">parser</span></code></a>模块的等效操作稍长一些,并允许将中间内部解析树保留为ST对象:</span></p><div class="highlight-python3"><div class="highlight"><pre><span></span><span class="gp">>>> </span><span class="kn">import</span> <span class="nn">parser</span>
|
||
<span class="gp">>>> </span><span class="n">st</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">expr</span><span class="p">(</span><span class="s1">'a + 5'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">code</span> <span class="o">=</span> <span class="n">st</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s1">'file.py'</span><span class="p">)</span>
|
||
<span class="gp">>>> </span><span class="n">a</span> <span class="o">=</span> <span class="mi">5</span>
|
||
<span class="gp">>>> </span><span class="nb">eval</span><span class="p">(</span><span class="n">code</span><span class="p">)</span>
|
||
<span class="go">10</span>
|
||
</pre></div></div><p><span class="yiyi-st" id="yiyi-139">需要ST和代码对象的应用程序可以将此代码打包成容易获得的函数:</span></p><div class="highlight-python3"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">parser</span>
|
||
|
||
<span class="k">def</span> <span class="nf">load_suite</span><span class="p">(</span><span class="n">source_string</span><span class="p">):</span>
|
||
<span class="n">st</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">suite</span><span class="p">(</span><span class="n">source_string</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">st</span><span class="p">,</span> <span class="n">st</span><span class="o">.</span><span class="n">compile</span><span class="p">()</span>
|
||
|
||
<span class="k">def</span> <span class="nf">load_expression</span><span class="p">(</span><span class="n">source_string</span><span class="p">):</span>
|
||
<span class="n">st</span> <span class="o">=</span> <span class="n">parser</span><span class="o">.</span><span class="n">expr</span><span class="p">(</span><span class="n">source_string</span><span class="p">)</span>
|
||
<span class="k">return</span> <span class="n">st</span><span class="p">,</span> <span class="n">st</span><span class="o">.</span><span class="n">compile</span><span class="p">()</span>
|
||
</pre></div></div></div></div></div> |