增加python文档

This commit is contained in:
2025-03-09 17:10:56 +08:00
parent 7153217140
commit 723430cade
1039 changed files with 699509 additions and 0 deletions

View File

@@ -0,0 +1,713 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>8. 复合语句 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="9. 最高层级组件" href="toplevel_components.html" />
<link rel="prev" title="7. 简单语句" href="simple_stmts.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/compound_stmts.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">8. 复合语句</a><ul>
<li><a class="reference internal" href="#the-if-statement">8.1. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-while-statement">8.2. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-for-statement">8.3. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-try-statement">8.4. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-with-statement">8.5. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> 语句</a></li>
<li><a class="reference internal" href="#function-definitions">8.6. 函数定义</a></li>
<li><a class="reference internal" href="#class-definitions">8.7. 类定义</a></li>
<li><a class="reference internal" href="#coroutines">8.8. 协程</a><ul>
<li><a class="reference internal" href="#coroutine-function-definition">8.8.1. 协程函数定义</a></li>
<li><a class="reference internal" href="#the-async-for-statement">8.8.2. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-async-with-statement">8.8.3. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">with</span></code> 语句</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="simple_stmts.html"
title="上一章"><span class="section-number">7. </span>简单语句</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="toplevel_components.html"
title="下一章"><span class="section-number">9. </span>最高层级组件</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/compound_stmts.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/compound_stmts.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="toplevel_components.html" title="9. 最高层级组件"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="simple_stmts.html" title="7. 简单语句"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="compound-statements">
<span id="compound"></span><h1><span class="section-number">8. </span>复合语句<a class="headerlink" href="#compound-statements" title="永久链接至标题"></a></h1>
<p id="index-0">复合语句是包含其它语句(语句组)的语句;它们会以某种方式影响或控制所包含其它语句的执行。 通常,复合语句会跨越多行,虽然在某些简单形式下整个复合语句也可能包含于一行之内。</p>
<p><a class="reference internal" href="#if"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a>, <a class="reference internal" href="#while"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code></a><a class="reference internal" href="#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> 语句用来实现传统的控制流程构造。 <a class="reference internal" href="#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句为一组语句指定异常处理和/和清理代码,而 <a class="reference internal" href="#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句允许在一个代码块周围执行初始化和终结化代码。 函数和类定义在语法上也属于复合语句。</p>
<p id="index-1">一条复合语句由一个或多个‘子句’组成。 一个子句则包含一个句头和一个‘句体’。 特定复合语句的子句头都处于相同的缩进层级。 每个子句头以一个作为唯一标识的关键字开始并以一个冒号结束。 子句体是由一个子句控制的一组语句。 子句体可以是在子句头的冒号之后与其同处一行的一条或由分号分隔的多条简单语句,或者也可以是在其之后缩进的一行或多行语句。 只有后一种形式的子句体才能包含嵌套的复合语句;以下形式是不合法的,这主要是因为无法分清某个后续的 <a class="reference internal" href="#else"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code></a> 子句应该属于哪个 <a class="reference internal" href="#if"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a> 子句:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">test1</span><span class="p">:</span> <span class="k">if</span> <span class="n">test2</span><span class="p">:</span> <span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</pre></div>
</div>
<p>还要注意的是在这种情形下分号的绑定比冒号更紧密,因此在以下示例中,所有 <a class="reference internal" href="../library/functions.html#print" title="print"><code class="xref py py-func docutils literal notranslate"><span class="pre">print()</span></code></a> 调用或者都不执行,或者都执行:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">y</span> <span class="o">&lt;</span> <span class="n">z</span><span class="p">:</span> <span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="p">);</span> <span class="nb">print</span><span class="p">(</span><span class="n">y</span><span class="p">);</span> <span class="nb">print</span><span class="p">(</span><span class="n">z</span><span class="p">)</span>
</pre></div>
</div>
<p>总结:</p>
<pre>
<strong id="grammar-token-compound-stmt">compound_stmt</strong> ::= <a class="reference internal" href="#grammar-token-if-stmt"><code class="xref docutils literal notranslate"><span class="pre">if_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-while-stmt"><code class="xref docutils literal notranslate"><span class="pre">while_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-for-stmt"><code class="xref docutils literal notranslate"><span class="pre">for_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-try-stmt"><code class="xref docutils literal notranslate"><span class="pre">try_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-with-stmt"><code class="xref docutils literal notranslate"><span class="pre">with_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-funcdef"><code class="xref docutils literal notranslate"><span class="pre">funcdef</span></code></a>
| <a class="reference internal" href="#grammar-token-classdef"><code class="xref docutils literal notranslate"><span class="pre">classdef</span></code></a>
| <a class="reference internal" href="#grammar-token-async-with-stmt"><code class="xref docutils literal notranslate"><span class="pre">async_with_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-async-for-stmt"><code class="xref docutils literal notranslate"><span class="pre">async_for_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-async-funcdef"><code class="xref docutils literal notranslate"><span class="pre">async_funcdef</span></code></a>
<strong id="grammar-token-suite">suite </strong> ::= <a class="reference internal" href="#grammar-token-stmt-list"><code class="xref docutils literal notranslate"><span class="pre">stmt_list</span></code></a> NEWLINE | NEWLINE INDENT <a class="reference internal" href="#grammar-token-statement"><code class="xref docutils literal notranslate"><span class="pre">statement</span></code></a>+ DEDENT
<strong id="grammar-token-statement">statement </strong> ::= <a class="reference internal" href="#grammar-token-stmt-list"><code class="xref docutils literal notranslate"><span class="pre">stmt_list</span></code></a> NEWLINE | <a class="reference internal" href="#grammar-token-compound-stmt"><code class="xref docutils literal notranslate"><span class="pre">compound_stmt</span></code></a>
<strong id="grammar-token-stmt-list">stmt_list </strong> ::= <a class="reference internal" href="simple_stmts.html#grammar-token-simple-stmt"><code class="xref docutils literal notranslate"><span class="pre">simple_stmt</span></code></a> (&quot;;&quot; <a class="reference internal" href="simple_stmts.html#grammar-token-simple-stmt"><code class="xref docutils literal notranslate"><span class="pre">simple_stmt</span></code></a>)* [&quot;;&quot;]
</pre>
<p id="index-2">请注意语句总是以 <code class="docutils literal notranslate"><span class="pre">NEWLINE</span></code> 结束,之后可能跟随一个 <code class="docutils literal notranslate"><span class="pre">DEDENT</span></code>。 还要注意可选的后续子句总是以一个不能作为语句开头的关键字作为开头,因此不会产生歧义(‘悬空的 <a class="reference internal" href="#else"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code></a>’问题在 Python 中是通过要求嵌套的 <a class="reference internal" href="#if"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a> 语句必须缩进来解决的)。</p>
<p>为了保证清晰,以下各节中语法规则采用将每个子句都放在单独行中的格式。</p>
<section id="the-if-statement">
<span id="else"></span><span id="elif"></span><span id="if"></span><h2><span class="section-number">8.1. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code> 语句<a class="headerlink" href="#the-if-statement" title="永久链接至标题"></a></h2>
<p id="index-3"><a class="reference internal" href="#if"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a> 语句用于有条件的执行:</p>
<pre>
<strong id="grammar-token-if-stmt">if_stmt</strong> ::= &quot;if&quot; <a class="reference internal" href="expressions.html#grammar-token-assignment-expression"><code class="xref docutils literal notranslate"><span class="pre">assignment_expression</span></code></a> &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
(&quot;elif&quot; <a class="reference internal" href="expressions.html#grammar-token-assignment-expression"><code class="xref docutils literal notranslate"><span class="pre">assignment_expression</span></code></a> &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>)*
[&quot;else&quot; &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>]
</pre>
<p>它通过对表达式逐个求值直至找到一个真值(请参阅 <a class="reference internal" href="expressions.html#booleans"><span class="std std-ref">布尔运算</span></a> 了解真值与假值的定义)在子句体中选择唯一匹配的一个;然后执行该子句体(而且 <a class="reference internal" href="#if"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code></a> 语句的其他部分不会被执行或求值)。 如果所有表达式均为假值,则如果 <a class="reference internal" href="#else"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code></a> 子句体如果存在就会被执行。</p>
</section>
<section id="the-while-statement">
<span id="while"></span><h2><span class="section-number">8.2. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code> 语句<a class="headerlink" href="#the-while-statement" title="永久链接至标题"></a></h2>
<p id="index-4"><a class="reference internal" href="#while"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code></a> 语句用于在表达式保持为真的情况下重复地执行:</p>
<pre>
<strong id="grammar-token-while-stmt">while_stmt</strong> ::= &quot;while&quot; <a class="reference internal" href="expressions.html#grammar-token-assignment-expression"><code class="xref docutils literal notranslate"><span class="pre">assignment_expression</span></code></a> &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
[&quot;else&quot; &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>]
</pre>
<p>这将重复地检验表达式,并且如果其值为真就执行第一个子句体;如果表达式值为假(这可能在第一次检验时就发生)则如果 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句体存在就会被执行并终止循环。</p>
<p id="index-5">第一个子句体中的 <a class="reference internal" href="simple_stmts.html#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a> 语句在执行时将终止循环且不执行 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句体。 第一个子句体中的 <a class="reference internal" href="simple_stmts.html#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> 语句在执行时将跳过子句体中的剩余部分并返回检验表达式。</p>
</section>
<section id="the-for-statement">
<span id="for"></span><h2><span class="section-number">8.3. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 语句<a class="headerlink" href="#the-for-statement" title="永久链接至标题"></a></h2>
<p id="index-6"><a class="reference internal" href="#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> 语句用于对序列(例如字符串、元组或列表)或其他可迭代对象中的元素进行迭代:</p>
<pre>
<strong id="grammar-token-for-stmt">for_stmt</strong> ::= &quot;for&quot; <a class="reference internal" href="simple_stmts.html#grammar-token-target-list"><code class="xref docutils literal notranslate"><span class="pre">target_list</span></code></a> &quot;in&quot; <a class="reference internal" href="expressions.html#grammar-token-expression-list"><code class="xref docutils literal notranslate"><span class="pre">expression_list</span></code></a> &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
[&quot;else&quot; &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>]
</pre>
<p>表达式列表会被求值一次;它应该产生一个可迭代对象。 系统将为 <code class="docutils literal notranslate"><span class="pre">expression_list</span></code> 的结果创建一个迭代器,然后将为迭代器所提供的每一项执行一次子句体,具体次序与迭代器的返回顺序一致。 每一项会按标准赋值规则 (参见 <a class="reference internal" href="simple_stmts.html#assignment"><span class="std std-ref">赋值语句</span></a>) 被依次赋值给目标列表,然后子句体将被执行。 当所有项被耗尽时 (这会在序列为空或迭代器引发 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 异常时立刻发生)<code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句的子句体如果存在将会被执行,并终止循环。</p>
<p id="index-7">第一个子句体中的 <a class="reference internal" href="simple_stmts.html#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a> 语句在执行时将终止循环且不执行 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句体。 第一个子句体中的 <a class="reference internal" href="simple_stmts.html#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> 语句在执行时将跳过子句体中的剩余部分并转往下一项继续执行,或者在没有下一项时转往 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句执行。</p>
<p>for 循环会对目标列表中的变量进行赋值。 这将覆盖之前对这些变量的所有赋值,包括在 for 循环体中的赋值:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">):</span>
<span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">5</span> <span class="c1"># this will not affect the for-loop</span>
<span class="c1"># because i will be overwritten with the next</span>
<span class="c1"># index in the range</span>
</pre></div>
</div>
<p id="index-8">目标列表中的名称在循环结束时不会被删除,但如果序列为空,则它们根本不会被循环所赋值。 提示:内置函数 <a class="reference internal" href="../library/stdtypes.html#range" title="range"><code class="xref py py-func docutils literal notranslate"><span class="pre">range()</span></code></a> 会返回一个可迭代的整数序列,适用于模拟 Pascal 中的 <code class="docutils literal notranslate"><span class="pre">for</span> <span class="pre">i</span> <span class="pre">:=</span> <span class="pre">a</span> <span class="pre">to</span> <span class="pre">b</span> <span class="pre">do</span></code> 这种效果;例如 <code class="docutils literal notranslate"><span class="pre">list(range(3))</span></code> 会返回列表 <code class="docutils literal notranslate"><span class="pre">[0,</span> <span class="pre">1,</span> <span class="pre">2]</span></code></p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p id="index-9">当序列在循环中被修改时会有一个微妙的问题(这只可能发生于可变序列例如列表中)。 会有一个内部计数器被用来跟踪下一个要使用的项,每次迭代都会使计数器递增。 当计数器值达到序列长度时循环就会终止。 这意味着如果语句体从序列中删除了当前(或之前)的一项,下一项就会被跳过(因为其标号将变成已被处理的当前项的标号)。 类似地,如果语句体在序列当前项的前面插入一个新项,当前项会在循环的下一轮中再次被处理。 这会导致麻烦的程序错误,避免此问题的办法是对整个序列使用切片来创建一个临时副本,例如</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">a</span><span class="p">[:]:</span>
<span class="k">if</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="mi">0</span><span class="p">:</span> <span class="n">a</span><span class="o">.</span><span class="n">remove</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</pre></div>
</div>
</div>
</section>
<section id="the-try-statement">
<span id="finally"></span><span id="except"></span><span id="try"></span><h2><span class="section-number">8.4. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 语句<a class="headerlink" href="#the-try-statement" title="永久链接至标题"></a></h2>
<p id="index-10"><a class="reference internal" href="#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句可为一组语句指定异常处理器和/或清理代码:</p>
<pre>
<strong id="grammar-token-try-stmt">try_stmt </strong> ::= <a class="reference internal" href="#grammar-token-try1-stmt"><code class="xref docutils literal notranslate"><span class="pre">try1_stmt</span></code></a> | <a class="reference internal" href="#grammar-token-try2-stmt"><code class="xref docutils literal notranslate"><span class="pre">try2_stmt</span></code></a>
<strong id="grammar-token-try1-stmt">try1_stmt</strong> ::= &quot;try&quot; &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
(&quot;except&quot; [<a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>]] &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>)+
[&quot;else&quot; &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>]
[&quot;finally&quot; &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>]
<strong id="grammar-token-try2-stmt">try2_stmt</strong> ::= &quot;try&quot; &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
&quot;finally&quot; &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
</pre>
<p><a class="reference internal" href="#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 子句指定一个或多个异常处理程序。 当 <a class="reference internal" href="#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 子句中没有发生异常时,没有任何异常处理程序会被执行。 当 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 子句中发生异常时,将启动对异常处理程序的搜索。 此搜索会逐一检查 except 子句直至找到与该异常相匹配的子句。 如果存在无表达式的 except 子句,它必须是最后一个;它将匹配任何异常。 对于带有表达式的 except 子句,该表达式会被求值,如果结果对象与发生的异常“兼容”则该子句将匹配该异常。 如果一个对象是异常对象所属的类或基类,或者是包含兼容该异常的项的元组则两者就是兼容的。</p>
<p>如果没有 except 子句与异常相匹配,则会在周边代码和发起调用栈上继续搜索异常处理器。 <a class="footnote-reference brackets" href="#id4" id="id1">1</a></p>
<p>如果在对 except 子句头中的表达式求值时引发了异常,则原来对处理器的搜索会被取消,并在周边代码和调用栈上启动对新异常的搜索(它会被视作是整个 <a class="reference internal" href="#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句所引发的异常)。</p>
<p id="index-11">当找到一个匹配的 except 子句时,该异常将被赋值给该 except 子句在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">as</span></code> 关键字之后指定的目标,如果存在此关键字的话,并且该 except 子句体将被执行。 所有 except 子句都必须有可执行的子句体。 当到达子句体的末尾时,通常会转向整个 try 语句之后继续执行。 (这意味着如果对于同一异常存在有嵌套的两个处理器,而异常发生于内层处理器的 try 子句中,则外层处理器将不会处理该异常。)</p>
<p>当使用 <code class="docutils literal notranslate"><span class="pre">as</span></code> 将目标赋值为一个异常时,它将在 except 子句结束时被清除。 这就相当于</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">except</span> <span class="n">E</span> <span class="k">as</span> <span class="n">N</span><span class="p">:</span>
<span class="n">foo</span>
</pre></div>
</div>
<p>被转写为</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">except</span> <span class="n">E</span> <span class="k">as</span> <span class="n">N</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">foo</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">del</span> <span class="n">N</span>
</pre></div>
</div>
<p>这意味着异常必须赋值给一个不同的名称才能在 except 子句之后引用它。 异常会被清除是因为在附加了回溯信息的情况下,它们会形成堆栈帧的循环引用,使得所有局部变量保持存活直到发生下一次垃圾回收。</p>
<p id="index-12">在一个 except 子句体被执行之前,有关异常的详细信息存放在 <a class="reference internal" href="../library/sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sys</span></code></a> 模块中,可通过 <a class="reference internal" href="../library/sys.html#sys.exc_info" title="sys.exc_info"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.exc_info()</span></code></a> 来访问。 <a class="reference internal" href="../library/sys.html#sys.exc_info" title="sys.exc_info"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.exc_info()</span></code></a> 返回一个 3 元组,由异常类、异常实例和回溯对象组成(参见 <a class="reference internal" href="datamodel.html#types"><span class="std std-ref">标准类型层级结构</span></a> 一节),用于在程序中标识异常发生点。 当从处理异常的函数返回时 <a class="reference internal" href="../library/sys.html#sys.exc_info" title="sys.exc_info"><code class="xref py py-func docutils literal notranslate"><span class="pre">sys.exc_info()</span></code></a> 的值会恢复为(调用前的)原值。</p>
<p id="index-13">如果控制流离开 <a class="reference internal" href="#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 子句体时没有引发异常,并且没有执行 <a class="reference internal" href="simple_stmts.html#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a>, <a class="reference internal" href="simple_stmts.html#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a><a class="reference internal" href="simple_stmts.html#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a> 语句,可选的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句将被执行。 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 语句中的异常不会由之前的 <a class="reference internal" href="#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 子句处理。</p>
<p id="index-14">如果存在 <a class="reference internal" href="#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a>,它将指定一个‘清理’处理程序。 <a class="reference internal" href="#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 子句会被执行,包括任何 <a class="reference internal" href="#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a><code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句。 如果在这些子句中发生任何未处理的异常,该异常会被临时保存。 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句将被执行。 如果存在被保存的异常,它会在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句的末尾被重新引发。 如果 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句引发了另一个异常,被保存的异常会被设为新异常的上下文。 如果 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句执行了 <a class="reference internal" href="simple_stmts.html#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a>, <a class="reference internal" href="simple_stmts.html#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a><a class="reference internal" href="simple_stmts.html#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> 语句,则被保存的异常会被丢弃:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="gp">... </span> <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="mi">1</span><span class="o">/</span><span class="mi">0</span>
<span class="gp">... </span> <span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">return</span> <span class="mi">42</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">f</span><span class="p">()</span>
<span class="go">42</span>
</pre></div>
</div>
<p><a class="reference internal" href="#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句执行期间,程序不能获取异常信息。</p>
<p id="index-15"><a class="reference internal" href="simple_stmts.html#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a>, <a class="reference internal" href="simple_stmts.html#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a><a class="reference internal" href="simple_stmts.html#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> 语句在一个 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code>...<code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 语句的 <a class="reference internal" href="#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 子语句体中被执行时,<a class="reference internal" href="#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子语句也会‘在离开时’被执行。</p>
<p>函数的返回值是由最后被执行的 <a class="reference internal" href="simple_stmts.html#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a> 语句所决定的。 由于 <a class="reference internal" href="#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句总是被执行,因此在 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句中被执行的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句总是最后被执行的:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
<span class="gp">... </span> <span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">return</span> <span class="s1">&#39;try&#39;</span>
<span class="gp">... </span> <span class="k">finally</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">return</span> <span class="s1">&#39;finally&#39;</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span><span class="p">()</span>
<span class="go">&#39;finally&#39;</span>
</pre></div>
</div>
<p>有关异常的更多信息可以在 <a class="reference internal" href="executionmodel.html#exceptions"><span class="std std-ref">异常</span></a> 一节找到,有关使用 <a class="reference internal" href="simple_stmts.html#raise"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code></a> 语句生成异常的信息可以在 <a class="reference internal" href="simple_stmts.html#raise"><span class="std std-ref">raise 语句</span></a> 一节找到。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.8 版更改: </span>在 Python 3.8 之前,<a class="reference internal" href="simple_stmts.html#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> 语句不允许在 <a class="reference internal" href="#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句中使用,这是因为具体实现存在一个问题。</p>
</div>
</section>
<section id="the-with-statement">
<span id="as"></span><span id="with"></span><h2><span class="section-number">8.5. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> 语句<a class="headerlink" href="#the-with-statement" title="永久链接至标题"></a></h2>
<p id="index-16"><a class="reference internal" href="#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句用于包装带有使用上下文管理器 (参见 <a class="reference internal" href="datamodel.html#context-managers"><span class="std std-ref">with 语句上下文管理器</span></a> 一节) 定义的方法的代码块的执行。 这允许对普通的 <a class="reference internal" href="#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a>...<a class="reference internal" href="#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a>...<a class="reference internal" href="#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 使用模式进行封装以方便地重用。</p>
<pre>
<strong id="grammar-token-with-stmt">with_stmt</strong> ::= &quot;with&quot; <a class="reference internal" href="#grammar-token-with-item"><code class="xref docutils literal notranslate"><span class="pre">with_item</span></code></a> (&quot;,&quot; <a class="reference internal" href="#grammar-token-with-item"><code class="xref docutils literal notranslate"><span class="pre">with_item</span></code></a>)* &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
<strong id="grammar-token-with-item">with_item</strong> ::= <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> [&quot;as&quot; <a class="reference internal" href="simple_stmts.html#grammar-token-target"><code class="xref docutils literal notranslate"><span class="pre">target</span></code></a>]
</pre>
<p>带有一个“项目”的 <a class="reference internal" href="#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句的执行过程如下:</p>
<ol class="arabic">
<li><p>对上下文表达式 (在 <a class="reference internal" href="#grammar-token-with-item"><code class="xref std std-token docutils literal notranslate"><span class="pre">with_item</span></code></a> 中给出的表达式) 求值以获得一个上下文管理器。</p></li>
<li><p>载入上下文管理器的 <a class="reference internal" href="datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> 以便后续使用。</p></li>
<li><p>载入上下文管理器的 <a class="reference internal" href="datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> 以便后续使用。</p></li>
<li><p>发起调用上下文管理器的 <a class="reference internal" href="datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> 方法。</p></li>
<li><p>如果 <a class="reference internal" href="#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句中包含一个目标,来自 <a class="reference internal" href="datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> 的返回值将被赋值给它。</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p><a class="reference internal" href="#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句会保证如果 <a class="reference internal" href="datamodel.html#object.__enter__" title="object.__enter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__enter__()</span></code></a> 方法返回时未发生错误,则 <a class="reference internal" href="datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> 将总是被调用。 因此,如果在对目标列表赋值期间发生错误,则会将其视为在语句体内部发生的错误。 参见下面的第 6 步。</p>
</div>
</li>
<li><p>执行语句体。</p></li>
<li><p>发起调用上下文管理器的 <a class="reference internal" href="datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> 方法。 如果语句体的退出是由异常导致的,则其类型、值和回溯信息将被作为参数传递给 <a class="reference internal" href="datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a>。 否则的话,将提供三个 <a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 参数。</p>
<p>如果语句体的退出是由异常导致的,并且来自 <a class="reference internal" href="datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> 方法的返回值为假,则该异常会被重新引发。 如果返回值为真,则该异常会被抑制,并会继续执行 <a class="reference internal" href="#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句之后的语句。</p>
<p>如果语句体由于异常以外的任何原因退出,则来自 <a class="reference internal" href="datamodel.html#object.__exit__" title="object.__exit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__exit__()</span></code></a> 的返回值会被忽略,并会在该类退出正常的发生位置继续执行。</p>
</li>
</ol>
<p>以下代码:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">EXPRESSION</span> <span class="k">as</span> <span class="n">TARGET</span><span class="p">:</span>
<span class="n">SUITE</span>
</pre></div>
</div>
<p>在语义上等价于:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">manager</span> <span class="o">=</span> <span class="p">(</span><span class="n">EXPRESSION</span><span class="p">)</span>
<span class="n">enter</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">manager</span><span class="p">)</span><span class="o">.</span><span class="fm">__enter__</span>
<span class="n">exit</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">manager</span><span class="p">)</span><span class="o">.</span><span class="fm">__exit__</span>
<span class="n">value</span> <span class="o">=</span> <span class="n">enter</span><span class="p">(</span><span class="n">manager</span><span class="p">)</span>
<span class="n">hit_except</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">TARGET</span> <span class="o">=</span> <span class="n">value</span>
<span class="n">SUITE</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">hit_except</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">exit</span><span class="p">(</span><span class="n">manager</span><span class="p">,</span> <span class="o">*</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()):</span>
<span class="k">raise</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">hit_except</span><span class="p">:</span>
<span class="n">exit</span><span class="p">(</span><span class="n">manager</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</pre></div>
</div>
<p>如果有多个项目,则会视作存在多个 <a class="reference internal" href="#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句嵌套来处理多个上下文管理器:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">A</span><span class="p">()</span> <span class="k">as</span> <span class="n">a</span><span class="p">,</span> <span class="n">B</span><span class="p">()</span> <span class="k">as</span> <span class="n">b</span><span class="p">:</span>
<span class="n">SUITE</span>
</pre></div>
</div>
<p>在语义上等价于:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">with</span> <span class="n">A</span><span class="p">()</span> <span class="k">as</span> <span class="n">a</span><span class="p">:</span>
<span class="k">with</span> <span class="n">B</span><span class="p">()</span> <span class="k">as</span> <span class="n">b</span><span class="p">:</span>
<span class="n">SUITE</span>
</pre></div>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.1 版更改: </span>支持多个上下文表达式。</p>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-50"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0343"><strong>PEP 343</strong></a> - &quot;with&quot; 语句</dt><dd><p>Python <a class="reference internal" href="#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句的规范描述、背景和示例。</p>
</dd>
</dl>
</div>
</section>
<section id="function-definitions">
<span id="def"></span><span id="function"></span><span id="index-18"></span><h2><span class="section-number">8.6. </span>函数定义<a class="headerlink" href="#function-definitions" title="永久链接至标题"></a></h2>
<p id="index-19">函数定义就是对用户自定义函数的定义(参见 <a class="reference internal" href="datamodel.html#types"><span class="std std-ref">标准类型层级结构</span></a> 一节):</p>
<pre>
<strong id="grammar-token-funcdef">funcdef </strong> ::= [<a class="reference internal" href="#grammar-token-decorators"><code class="xref docutils literal notranslate"><span class="pre">decorators</span></code></a>] &quot;def&quot; <a class="reference internal" href="#grammar-token-funcname"><code class="xref docutils literal notranslate"><span class="pre">funcname</span></code></a> &quot;(&quot; [<a class="reference internal" href="#grammar-token-parameter-list"><code class="xref docutils literal notranslate"><span class="pre">parameter_list</span></code></a>] &quot;)&quot;
[&quot;-&gt;&quot; <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>] &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
<strong id="grammar-token-decorators">decorators </strong> ::= <a class="reference internal" href="#grammar-token-decorator"><code class="xref docutils literal notranslate"><span class="pre">decorator</span></code></a>+
<strong id="grammar-token-decorator">decorator </strong> ::= &quot;&#64;&quot; <a class="reference internal" href="#grammar-token-dotted-name"><code class="xref docutils literal notranslate"><span class="pre">dotted_name</span></code></a> [&quot;(&quot; [<a class="reference internal" href="expressions.html#grammar-token-argument-list"><code class="xref docutils literal notranslate"><span class="pre">argument_list</span></code></a> [&quot;,&quot;]] &quot;)&quot;] NEWLINE
<strong id="grammar-token-dotted-name">dotted_name </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> (&quot;.&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>)*
<strong id="grammar-token-parameter-list">parameter_list </strong> ::= <a class="reference internal" href="#grammar-token-defparameter"><code class="xref docutils literal notranslate"><span class="pre">defparameter</span></code></a> (&quot;,&quot; <a class="reference internal" href="#grammar-token-defparameter"><code class="xref docutils literal notranslate"><span class="pre">defparameter</span></code></a>)* &quot;,&quot; &quot;/&quot; [&quot;,&quot; [<a class="reference internal" href="#grammar-token-parameter-list-no-posonly"><code class="xref docutils literal notranslate"><span class="pre">parameter_list_no_posonly</span></code></a>]]
| <a class="reference internal" href="#grammar-token-parameter-list-no-posonly"><code class="xref docutils literal notranslate"><span class="pre">parameter_list_no_posonly</span></code></a>
<strong id="grammar-token-parameter-list-no-posonly">parameter_list_no_posonly</strong> ::= <a class="reference internal" href="#grammar-token-defparameter"><code class="xref docutils literal notranslate"><span class="pre">defparameter</span></code></a> (&quot;,&quot; <a class="reference internal" href="#grammar-token-defparameter"><code class="xref docutils literal notranslate"><span class="pre">defparameter</span></code></a>)* [&quot;,&quot; [<a class="reference internal" href="#grammar-token-parameter-list-starargs"><code class="xref docutils literal notranslate"><span class="pre">parameter_list_starargs</span></code></a>]]
| <a class="reference internal" href="#grammar-token-parameter-list-starargs"><code class="xref docutils literal notranslate"><span class="pre">parameter_list_starargs</span></code></a>
<strong id="grammar-token-parameter-list-starargs">parameter_list_starargs </strong> ::= &quot;*&quot; [<a class="reference internal" href="#grammar-token-parameter"><code class="xref docutils literal notranslate"><span class="pre">parameter</span></code></a>] (&quot;,&quot; <a class="reference internal" href="#grammar-token-defparameter"><code class="xref docutils literal notranslate"><span class="pre">defparameter</span></code></a>)* [&quot;,&quot; [&quot;**&quot; <a class="reference internal" href="#grammar-token-parameter"><code class="xref docutils literal notranslate"><span class="pre">parameter</span></code></a> [&quot;,&quot;]]]
| &quot;**&quot; <a class="reference internal" href="#grammar-token-parameter"><code class="xref docutils literal notranslate"><span class="pre">parameter</span></code></a> [&quot;,&quot;]
<strong id="grammar-token-parameter">parameter </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> [&quot;:&quot; <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>]
<strong id="grammar-token-defparameter">defparameter </strong> ::= <a class="reference internal" href="#grammar-token-parameter"><code class="xref docutils literal notranslate"><span class="pre">parameter</span></code></a> [&quot;=&quot; <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>]
<strong id="grammar-token-funcname">funcname </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>
</pre>
<p>函数定义是一条可执行语句。 它执行时会在当前局部命名空间中将函数名称绑定到一个函数对象(函数可执行代码的包装器)。 这个函数对象包含对当前全局命名空间的引用,作为函数被调用时所使用的全局命名空间。</p>
<p>函数定义并不会执行函数体;只有当函数被调用时才会执行此操作。 <a class="footnote-reference brackets" href="#id5" id="id2">2</a></p>
<p id="index-20">一个函数定义可以被一个或多个 <a class="reference internal" href="../glossary.html#term-decorator"><span class="xref std std-term">decorator</span></a> 表达式所包装。 当函数被定义时将在包含该函数定义的作用域中对装饰器表达式求值。 求值结果必须是一个可调用对象,它会以该函数对象作为唯一参数被发起调用。 其返回值将被绑定到函数名称而非函数对象。 多个装饰器会以嵌套方式被应用。 例如以下代码</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@f1</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
<span class="nd">@f2</span>
<span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span>
</pre></div>
</div>
<p>大致等价于</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">func</span><span class="p">():</span> <span class="k">pass</span>
<span class="n">func</span> <span class="o">=</span> <span class="n">f1</span><span class="p">(</span><span class="n">arg</span><span class="p">)(</span><span class="n">f2</span><span class="p">(</span><span class="n">func</span><span class="p">))</span>
</pre></div>
</div>
<p>不同之处在于原始函数并不会被临时绑定到名称 <code class="docutils literal notranslate"><span class="pre">func</span></code></p>
<p id="index-21">当一个或多个 <a class="reference internal" href="../glossary.html#term-parameter"><span class="xref std std-term">形参</span></a> 具有 <em>形参</em> <code class="docutils literal notranslate"><span class="pre">=</span></code> <em>表达式</em> 这样的形式时,该函数就被称为具有“默认形参值”。 对于一个具有默认值的形参,其对应的 <a class="reference internal" href="../glossary.html#term-argument"><span class="xref std std-term">argument</span></a> 可以在调用中被省略,在此情况下会用形参的默认值来替代。 如果一个形参具有默认值,后续所有在 &quot;<code class="docutils literal notranslate"><span class="pre">*</span></code>&quot; 之前的形参也必须具有默认值 --- 这个句法限制并未在语法中明确表达。</p>
<p><strong>默认形参值会在执行函数定义时按从左至右的顺序被求值。</strong> 这意味着当函数被定义时将对表达式求值一次,相同的“预计算”值将在每次调用时被使用。 这一点在默认形参为可变对象,例如列表或字典的时候尤其需要重点理解:如果函数修改了该对象(例如向列表添加了一项),则实际上默认值也会被修改。 这通常不是人们所预期的。 绕过此问题的一个方法是使用 <code class="docutils literal notranslate"><span class="pre">None</span></code> 作为默认值,并在函数体中显式地对其进行测试,例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">whats_on_the_telly</span><span class="p">(</span><span class="n">penguin</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
<span class="k">if</span> <span class="n">penguin</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">penguin</span> <span class="o">=</span> <span class="p">[]</span>
<span class="n">penguin</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="s2">&quot;property of the zoo&quot;</span><span class="p">)</span>
<span class="k">return</span> <span class="n">penguin</span>
</pre></div>
</div>
<p id="index-22">函数调用的语义在 <a class="reference internal" href="expressions.html#calls"><span class="std std-ref">调用</span></a> 一节中有更详细的描述。 函数调用总是会给形参列表中列出的所有形参赋值,或是用位置参数,或是用关键字参数,或是用默认值。 如果存在 &quot;<code class="docutils literal notranslate"><span class="pre">*identifier</span></code>&quot; 这样的形式,它会被初始化为一个元组来接收任何额外的位置参数,默认为一个空元组。 如果存在 &quot;<code class="docutils literal notranslate"><span class="pre">**identifier</span></code>&quot; 这样的形式,它会被初始化为一个新的有序映射来接收任何额外的关键字参数,默认为一个相同类型的空映射。 在 &quot;<code class="docutils literal notranslate"><span class="pre">*</span></code>&quot;&quot;<code class="docutils literal notranslate"><span class="pre">*identifier</span></code>&quot; 之后的形参都是仅限关键字形参因而只能通过关键字参数传入。 在 &quot;<code class="docutils literal notranslate"><span class="pre">/</span></code>&quot; 之前的形参都是仅限位置形参因而只能通过位置参数传入。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.8 版更改: </span>可以使用 <code class="docutils literal notranslate"><span class="pre">/</span></code> 函数形参语法来标示仅限位置形参。 请参阅 <span class="target" id="index-51"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0570"><strong>PEP 570</strong></a> 了解详情。</p>
</div>
<p id="index-24">形参可以带有 <a class="reference internal" href="../glossary.html#term-function-annotation"><span class="xref std std-term">标注</span></a>,其形式为在形参名称后加上 &quot;<code class="docutils literal notranslate"><span class="pre">:</span> <span class="pre">expression</span></code>&quot;。 任何形参都可以带有标注,甚至 <code class="docutils literal notranslate"><span class="pre">*identifier</span></code><code class="docutils literal notranslate"><span class="pre">**identifier</span></code> 这样的形参也可以。 函数可以带有“返回”标注,其形式为在形参列表后加上 &quot;<code class="docutils literal notranslate"><span class="pre">-&gt;</span> <span class="pre">expression</span></code>&quot;。 这些标注可以是任何有效的 Python 表达式。 标注的存在不会改变函数的语义。 标注值可以作为函数对象的 <code class="xref py py-attr docutils literal notranslate"><span class="pre">__annotations__</span></code> 属性中以对应形参名称为键的字典值被访问。 如果使用了 <code class="docutils literal notranslate"><span class="pre">annotations</span></code> import from <a class="reference internal" href="../library/__future__.html#module-__future__" title="__future__: Future statement definitions"><code class="xref py py-mod docutils literal notranslate"><span class="pre">__future__</span></code></a> 的方式,则标注会在运行时保存为字符串以启用延迟求值特性。 否则,它们会在执行函数定义时被求值。 在这种情况下,标注的求值顺序可能与它们在源代码中出现的顺序不同。</p>
<p id="index-25">创建匿名函数(未绑定到一个名称的函数)以便立即在表达式中使用也是可能的。 这需要使用 lambda 表达式,具体描述见 <a class="reference internal" href="expressions.html#lambda"><span class="std std-ref">lambda 表达式</span></a> 一节。 请注意 lambda 只是简单函数定义的一种简化写法;在 &quot;<a class="reference internal" href="#def"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">def</span></code></a>&quot; 语句中定义的函数也可以像用 lambda 表达式定义的函数一样被传递或赋值给其他名称。 &quot;<code class="xref std std-keyword docutils literal notranslate"><span class="pre">def</span></code>&quot; 形式实际上更为强大,因为它允许执行多条语句和使用标注。</p>
<p><strong>程序员注意事项:</strong> 函数属于一类对象。 在一个函数内部执行的 &quot;<code class="docutils literal notranslate"><span class="pre">def</span></code>&quot; 语句会定义一个局部函数并可被返回或传递。 在嵌套函数中使用的自由变量可以访问包含该 def 语句的函数的局部变量。 详情参见 <a class="reference internal" href="executionmodel.html#naming"><span class="std std-ref">命名与绑定</span></a> 一节。</p>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-52"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3107"><strong>PEP 3107</strong></a> - 函数标注</dt><dd><p>最初的函数标注规范说明。</p>
</dd>
<dt><span class="target" id="index-53"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0484"><strong>PEP 484</strong></a> - 类型提示</dt><dd><p>标注的标准含意定义:类型提示。</p>
</dd>
<dt><span class="target" id="index-54"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0526"><strong>PEP 526</strong></a> - 变量标注的语法</dt><dd><p>变量声明的类型提示功能,包括类变量和实例变量</p>
</dd>
<dt><span class="target" id="index-55"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0563"><strong>PEP 563</strong></a> - 延迟的标注求值</dt><dd><p>支持在运行时通过以字符串形式保存标注而非不是即求值来实现标注内部的向前引用。</p>
</dd>
</dl>
</div>
</section>
<section id="class-definitions">
<span id="class"></span><h2><span class="section-number">8.7. </span>类定义<a class="headerlink" href="#class-definitions" title="永久链接至标题"></a></h2>
<p id="index-30">类定义就是对类对象的定义 (参见 <a class="reference internal" href="datamodel.html#types"><span class="std std-ref">标准类型层级结构</span></a> 一节):</p>
<pre>
<strong id="grammar-token-classdef">classdef </strong> ::= [<a class="reference internal" href="#grammar-token-decorators"><code class="xref docutils literal notranslate"><span class="pre">decorators</span></code></a>] &quot;class&quot; <a class="reference internal" href="#grammar-token-classname"><code class="xref docutils literal notranslate"><span class="pre">classname</span></code></a> [<a class="reference internal" href="#grammar-token-inheritance"><code class="xref docutils literal notranslate"><span class="pre">inheritance</span></code></a>] &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
<strong id="grammar-token-inheritance">inheritance</strong> ::= &quot;(&quot; [<a class="reference internal" href="expressions.html#grammar-token-argument-list"><code class="xref docutils literal notranslate"><span class="pre">argument_list</span></code></a>] &quot;)&quot;
<strong id="grammar-token-classname">classname </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>
</pre>
<p>类定义是一条可执行语句。 其中继承列表通常给出基类的列表 (进阶用法请参见 <a class="reference internal" href="datamodel.html#metaclasses"><span class="std std-ref">元类</span></a>),列表中的每一项都应当被求值为一个允许子类的类对象。 没有继承列表的类默认继承自基类 <a class="reference internal" href="../library/functions.html#object" title="object"><code class="xref py py-class docutils literal notranslate"><span class="pre">object</span></code></a>;因此,:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span>
<span class="k">pass</span>
</pre></div>
</div>
<p>等价于</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Foo</span><span class="p">(</span><span class="nb">object</span><span class="p">):</span>
<span class="k">pass</span>
</pre></div>
</div>
<p>随后类体将在一个新的执行帧 (参见 <a class="reference internal" href="executionmodel.html#naming"><span class="std std-ref">命名与绑定</span></a>) 中被执行,使用新创建的局部命名空间和原有的全局命名空间。 (通常,类体主要包含函数定义。) 当类体结束执行时,其执行帧将被丢弃而其局部命名空间会被保存。 <a class="footnote-reference brackets" href="#id6" id="id3">3</a> 一个类对象随后会被创建,其基类使用给定的继承列表,属性字典使用保存的局部命名空间。 类名称将在原有的全局命名空间中绑定到该类对象。</p>
<p>在类体内定义的属性的顺序保存在新类的 <code class="docutils literal notranslate"><span class="pre">__dict__</span></code> 中。 请注意此顺序的可靠性只限于类刚被创建时,并且只适用于使用定义语法所定义的类。</p>
<p>类的创建可使用 <a class="reference internal" href="datamodel.html#metaclasses"><span class="std std-ref">元类</span></a> 进行重度定制。</p>
<p id="index-31">类也可以被装饰:就像装饰函数一样,:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nd">@f1</span><span class="p">(</span><span class="n">arg</span><span class="p">)</span>
<span class="nd">@f2</span>
<span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span> <span class="k">pass</span>
</pre></div>
</div>
<p>大致等价于</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Foo</span><span class="p">:</span> <span class="k">pass</span>
<span class="n">Foo</span> <span class="o">=</span> <span class="n">f1</span><span class="p">(</span><span class="n">arg</span><span class="p">)(</span><span class="n">f2</span><span class="p">(</span><span class="n">Foo</span><span class="p">))</span>
</pre></div>
</div>
<p>装饰器表达式的求值规则与函数装饰器相同。 结果随后会被绑定到类名称。</p>
<p><strong>程序员注意事项:</strong> 在类定义内定义的变量是类属性;它们将被类实例所共享。 实例属性可通过 <code class="docutils literal notranslate"><span class="pre">self.name</span> <span class="pre">=</span> <span class="pre">value</span></code> 在方法中设定。 类和实例属性均可通过 &quot;<code class="docutils literal notranslate"><span class="pre">self.name</span></code>&quot; 表示法来访问,当通过此方式访问时实例属性会隐藏同名的类属性。 类属性可被用作实例属性的默认值,但在此场景下使用可变值可能导致未预期的结果。 可以使用 <a class="reference internal" href="datamodel.html#descriptors"><span class="std std-ref">描述器</span></a> 来创建具有不同实现细节的实例变量。</p>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-56"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3115"><strong>PEP 3115</strong></a> - Python 3000 中的元类</dt><dd><p>将元类声明修改为当前语法的提议,以及关于如何构建带有元类的类的语义描述。</p>
</dd>
<dt><span class="target" id="index-57"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3129"><strong>PEP 3129</strong></a> - 类装饰器</dt><dd><p>增加类装饰器的提议。 函数和方法装饰器是在 <span class="target" id="index-58"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0318"><strong>PEP 318</strong></a> 中被引入的。</p>
</dd>
</dl>
</div>
</section>
<section id="coroutines">
<span id="async"></span><h2><span class="section-number">8.8. </span>协程<a class="headerlink" href="#coroutines" title="永久链接至标题"></a></h2>
<div class="versionadded">
<p><span class="versionmodified added">3.5 新版功能.</span></p>
</div>
<section id="coroutine-function-definition">
<span id="async-def"></span><span id="index-35"></span><h3><span class="section-number">8.8.1. </span>协程函数定义<a class="headerlink" href="#coroutine-function-definition" title="永久链接至标题"></a></h3>
<pre>
<strong id="grammar-token-async-funcdef">async_funcdef</strong> ::= [<a class="reference internal" href="#grammar-token-decorators"><code class="xref docutils literal notranslate"><span class="pre">decorators</span></code></a>] &quot;async&quot; &quot;def&quot; <a class="reference internal" href="#grammar-token-funcname"><code class="xref docutils literal notranslate"><span class="pre">funcname</span></code></a> &quot;(&quot; [<a class="reference internal" href="#grammar-token-parameter-list"><code class="xref docutils literal notranslate"><span class="pre">parameter_list</span></code></a>] &quot;)&quot;
[&quot;-&gt;&quot; <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>] &quot;:&quot; <a class="reference internal" href="#grammar-token-suite"><code class="xref docutils literal notranslate"><span class="pre">suite</span></code></a>
</pre>
<p id="index-36">Python 协程可以在多个位置上挂起和恢复执行 (参见 <a class="reference internal" href="../glossary.html#term-coroutine"><span class="xref std std-term">coroutine</span></a>)。 在协程函数体内部,<code class="docutils literal notranslate"><span class="pre">await</span></code><code class="docutils literal notranslate"><span class="pre">async</span></code> 标识符已成为保留关键字;<a class="reference internal" href="expressions.html#await"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code></a> 表达式,<a class="reference internal" href="#async-for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code></a> 以及 <a class="reference internal" href="#async-with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">with</span></code></a> 只能在协程函数体中使用。</p>
<p>使用 <code class="docutils literal notranslate"><span class="pre">async</span> <span class="pre">def</span></code> 语法定义的函数总是为协程函数,即使它们不包含 <code class="docutils literal notranslate"><span class="pre">await</span></code><code class="docutils literal notranslate"><span class="pre">async</span></code> 关键字。</p>
<p>在协程函数体中使用 <code class="docutils literal notranslate"><span class="pre">yield</span> <span class="pre">from</span></code> 表达式将引发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a></p>
<p>协程函数的例子:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">def</span> <span class="nf">func</span><span class="p">(</span><span class="n">param1</span><span class="p">,</span> <span class="n">param2</span><span class="p">):</span>
<span class="n">do_stuff</span><span class="p">()</span>
<span class="k">await</span> <span class="n">some_coroutine</span><span class="p">()</span>
</pre></div>
</div>
</section>
<section id="the-async-for-statement">
<span id="async-for"></span><span id="index-37"></span><h3><span class="section-number">8.8.2. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 语句<a class="headerlink" href="#the-async-for-statement" title="永久链接至标题"></a></h3>
<pre>
<strong id="grammar-token-async-for-stmt">async_for_stmt</strong> ::= &quot;async&quot; <a class="reference internal" href="#grammar-token-for-stmt"><code class="xref docutils literal notranslate"><span class="pre">for_stmt</span></code></a>
</pre>
<p><a class="reference internal" href="../glossary.html#term-asynchronous-iterable"><span class="xref std std-term">asynchronous iterable</span></a> 能够在其 <em>iter</em> 实现中调用异步代码,而 <a class="reference internal" href="../glossary.html#term-asynchronous-iterator"><span class="xref std std-term">asynchronous iterator</span></a> 可以在其 <em>next</em> 方法中调用异步代码。</p>
<p><code class="docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 语句允许方便地对异步迭代器进行迭代。</p>
<p>以下代码:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">for</span> <span class="n">TARGET</span> <span class="ow">in</span> <span class="n">ITER</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">SUITE2</span>
</pre></div>
</div>
<p>在语义上等价于:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="nb">iter</span> <span class="o">=</span> <span class="p">(</span><span class="n">ITER</span><span class="p">)</span>
<span class="nb">iter</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="nb">iter</span><span class="p">)</span><span class="o">.</span><span class="fm">__aiter__</span><span class="p">(</span><span class="nb">iter</span><span class="p">)</span>
<span class="n">running</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">while</span> <span class="n">running</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">TARGET</span> <span class="o">=</span> <span class="k">await</span> <span class="nb">type</span><span class="p">(</span><span class="nb">iter</span><span class="p">)</span><span class="o">.</span><span class="fm">__anext__</span><span class="p">(</span><span class="nb">iter</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">StopAsyncIteration</span><span class="p">:</span>
<span class="n">running</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">SUITE</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">SUITE2</span>
</pre></div>
</div>
<p>另请参阅 <a class="reference internal" href="datamodel.html#object.__aiter__" title="object.__aiter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__aiter__()</span></code></a><a class="reference internal" href="datamodel.html#object.__anext__" title="object.__anext__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__anext__()</span></code></a> 了解详情。</p>
<p>在协程函数体之外使用 <code class="docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 语句将引发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a></p>
</section>
<section id="the-async-with-statement">
<span id="async-with"></span><span id="index-38"></span><h3><span class="section-number">8.8.3. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">with</span></code> 语句<a class="headerlink" href="#the-async-with-statement" title="永久链接至标题"></a></h3>
<pre>
<strong id="grammar-token-async-with-stmt">async_with_stmt</strong> ::= &quot;async&quot; <a class="reference internal" href="#grammar-token-with-stmt"><code class="xref docutils literal notranslate"><span class="pre">with_stmt</span></code></a>
</pre>
<p><a class="reference internal" href="../glossary.html#term-asynchronous-context-manager"><span class="xref std std-term">asynchronous context manager</span></a> 是一种 <a class="reference internal" href="../glossary.html#term-context-manager"><span class="xref std std-term">context manager</span></a>,能够在其 <em>enter</em><em>exit</em> 方法中暂停执行。</p>
<p>以下代码:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">async</span> <span class="k">with</span> <span class="n">EXPRESSION</span> <span class="k">as</span> <span class="n">TARGET</span><span class="p">:</span>
<span class="n">SUITE</span>
</pre></div>
</div>
<p>在语义上等价于:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">manager</span> <span class="o">=</span> <span class="p">(</span><span class="n">EXPRESSION</span><span class="p">)</span>
<span class="n">aexit</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">manager</span><span class="p">)</span><span class="o">.</span><span class="fm">__aexit__</span>
<span class="n">aenter</span> <span class="o">=</span> <span class="nb">type</span><span class="p">(</span><span class="n">manager</span><span class="p">)</span><span class="o">.</span><span class="fm">__aenter__</span>
<span class="n">value</span> <span class="o">=</span> <span class="k">await</span> <span class="n">aenter</span><span class="p">(</span><span class="n">manager</span><span class="p">)</span>
<span class="n">hit_except</span> <span class="o">=</span> <span class="kc">False</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">TARGET</span> <span class="o">=</span> <span class="n">value</span>
<span class="n">SUITE</span>
<span class="k">except</span><span class="p">:</span>
<span class="n">hit_except</span> <span class="o">=</span> <span class="kc">True</span>
<span class="k">if</span> <span class="ow">not</span> <span class="k">await</span> <span class="n">aexit</span><span class="p">(</span><span class="n">manager</span><span class="p">,</span> <span class="o">*</span><span class="n">sys</span><span class="o">.</span><span class="n">exc_info</span><span class="p">()):</span>
<span class="k">raise</span>
<span class="k">finally</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">hit_except</span><span class="p">:</span>
<span class="k">await</span> <span class="n">aexit</span><span class="p">(</span><span class="n">manager</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">,</span> <span class="kc">None</span><span class="p">)</span>
</pre></div>
</div>
<p>另请参阅 <a class="reference internal" href="datamodel.html#object.__aenter__" title="object.__aenter__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__aenter__()</span></code></a><a class="reference internal" href="datamodel.html#object.__aexit__" title="object.__aexit__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__aexit__()</span></code></a> 了解详情。</p>
<p>在协程函数体之外使用 <code class="docutils literal notranslate"><span class="pre">async</span> <span class="pre">with</span></code> 语句将引发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a></p>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-59"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0492"><strong>PEP 492</strong></a> - 使用 async 和 await 语法实现协程</dt><dd><p>将协程作为 Python 中的一个正式的单独概念,并增加相应的支持语法。</p>
</dd>
</dl>
</div>
<p class="rubric">备注</p>
<dl class="footnote brackets">
<dt class="label" id="id4"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p>异常会被传播给发起调用栈,除非存在一个 <a class="reference internal" href="#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句正好引发了另一个异常。 新引发的异常将导致旧异常的丢失。</p>
</dd>
<dt class="label" id="id5"><span class="brackets"><a class="fn-backref" href="#id2">2</a></span></dt>
<dd><p>作为函数体的第一条语句出现的字符串字面值会被转换为函数的 <code class="docutils literal notranslate"><span class="pre">__doc__</span></code> 属性,也就是该函数的 <a class="reference internal" href="../glossary.html#term-docstring"><span class="xref std std-term">docstring</span></a></p>
</dd>
<dt class="label" id="id6"><span class="brackets"><a class="fn-backref" href="#id3">3</a></span></dt>
<dd><p>作为类体的第一条语句出现的字符串字面值会被转换为命名空间的 <code class="docutils literal notranslate"><span class="pre">__doc__</span></code> 条目,也就是该类的 <a class="reference internal" href="../glossary.html#term-docstring"><span class="xref std std-term">docstring</span></a></p>
</dd>
</dl>
</section>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">8. 复合语句</a><ul>
<li><a class="reference internal" href="#the-if-statement">8.1. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-while-statement">8.2. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-for-statement">8.3. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-try-statement">8.4. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-with-statement">8.5. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> 语句</a></li>
<li><a class="reference internal" href="#function-definitions">8.6. 函数定义</a></li>
<li><a class="reference internal" href="#class-definitions">8.7. 类定义</a></li>
<li><a class="reference internal" href="#coroutines">8.8. 协程</a><ul>
<li><a class="reference internal" href="#coroutine-function-definition">8.8.1. 协程函数定义</a></li>
<li><a class="reference internal" href="#the-async-for-statement">8.8.2. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-async-with-statement">8.8.3. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">with</span></code> 语句</a></li>
</ul>
</li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="simple_stmts.html"
title="上一章"><span class="section-number">7. </span>简单语句</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="toplevel_components.html"
title="下一章"><span class="section-number">9. </span>最高层级组件</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/compound_stmts.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="toplevel_components.html" title="9. 最高层级组件"
>下一页</a> |</li>
<li class="right" >
<a href="simple_stmts.html" title="7. 简单语句"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,356 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>4. 执行模型 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="5. 导入系统" href="import.html" />
<link rel="prev" title="3. 数据模型" href="datamodel.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/executionmodel.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">4. 执行模型</a><ul>
<li><a class="reference internal" href="#structure-of-a-program">4.1. 程序的结构</a></li>
<li><a class="reference internal" href="#naming-and-binding">4.2. 命名与绑定</a><ul>
<li><a class="reference internal" href="#binding-of-names">4.2.1. 名称的绑定</a></li>
<li><a class="reference internal" href="#resolution-of-names">4.2.2. 名称的解析</a></li>
<li><a class="reference internal" href="#builtins-and-restricted-execution">4.2.3. 内置命名空间和受限的执行</a></li>
<li><a class="reference internal" href="#interaction-with-dynamic-features">4.2.4. 与动态特性的交互</a></li>
</ul>
</li>
<li><a class="reference internal" href="#exceptions">4.3. 异常</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="datamodel.html"
title="上一章"><span class="section-number">3. </span>数据模型</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="import.html"
title="下一章"><span class="section-number">5. </span>导入系统</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/executionmodel.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/executionmodel.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="import.html" title="5. 导入系统"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="datamodel.html" title="3. 数据模型"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="execution-model">
<span id="execmodel"></span><h1><span class="section-number">4. </span>执行模型<a class="headerlink" href="#execution-model" title="永久链接至标题"></a></h1>
<section id="structure-of-a-program">
<span id="prog-structure"></span><span id="index-0"></span><h2><span class="section-number">4.1. </span>程序的结构<a class="headerlink" href="#structure-of-a-program" title="永久链接至标题"></a></h2>
<p id="index-1">Python 程序是由代码块构成的。 <em class="dfn">代码块</em> 是被作为一个单元来执行的一段 Python 程序文本。 以下几个都是代码块:模块、函数体和类定义。 交互式输入的每条命令都是一个代码块。 一个脚本文件(作为标准输入发送给解释器或是作为命令行参数发送给解释器的文件)也是一个代码块。 一条脚本命令(通过 <a class="reference internal" href="../using/cmdline.html#cmdoption-c"><code class="xref std std-option docutils literal notranslate"><span class="pre">-c</span></code></a> 选项在解释器命令行中指定的命令)也是一个代码块。 传递给内置函数 <a class="reference internal" href="../library/functions.html#eval" title="eval"><code class="xref py py-func docutils literal notranslate"><span class="pre">eval()</span></code></a><a class="reference internal" href="../library/functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a> 的字符串参数也是代码块。</p>
<p id="index-2">代码块在 <em class="dfn">执行帧</em> 中被执行。 一个帧会包含某些管理信息(用于调试)并决定代码块执行完成后应前往何处以及如何继续执行。</p>
</section>
<section id="naming-and-binding">
<span id="naming"></span><h2><span class="section-number">4.2. </span>命名与绑定<a class="headerlink" href="#naming-and-binding" title="永久链接至标题"></a></h2>
<section id="binding-of-names">
<span id="bind-names"></span><span id="index-3"></span><h3><span class="section-number">4.2.1. </span>名称的绑定<a class="headerlink" href="#binding-of-names" title="永久链接至标题"></a></h3>
<p id="index-4"><em class="dfn">名称</em> 用于指代对象。 名称是通过名称绑定操作来引入的。</p>
<p id="index-5">以下构造会绑定名称:传给函数的正式形参,<a class="reference internal" href="simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句,类与函数定义(这会在定义的代码块中绑定类或函数名称)以及发生以标识符为目标的赋值,<a class="reference internal" href="compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> 循环的开头,或 <a class="reference internal" href="compound_stmts.html#with"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code></a> 语句和 <a class="reference internal" href="compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 子句的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">as</span></code> 之后。 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code> 语句的 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">...</span> <span class="pre">import</span> <span class="pre">*</span></code> 形式会绑定在被导入模块中定义的所有名称,那些以下划线开头的除外。 这种形式仅在模块层级上被使用。</p>
<p><a class="reference internal" href="simple_stmts.html#del"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">del</span></code></a> 语句的目标也被视作一种绑定(虽然其实际语义为解除名称绑定)。</p>
<p>每条赋值或导入语句均发生于类或函数内部定义的代码块中,或是发生于模块层级(即最高层级的代码块)。</p>
<p id="index-6">如果名称绑定在一个代码块中,则为该代码块的局部变量,除非声明为 <a class="reference internal" href="simple_stmts.html#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a><a class="reference internal" href="simple_stmts.html#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a>。 如果名称绑定在模块层级,则为全局变量。 (模块代码块的变量既为局部变量又为全局变量。) 如果变量在一个代码块中被使用但不是在其中定义,则为 <em class="dfn">自由变量</em></p>
<p>每个在程序文本中出现的名称是指由以下名称解析规则所建立的对该名称的 <em class="dfn">绑定</em></p>
</section>
<section id="resolution-of-names">
<span id="resolve-names"></span><h3><span class="section-number">4.2.2. </span>名称的解析<a class="headerlink" href="#resolution-of-names" title="永久链接至标题"></a></h3>
<p id="index-7"><em class="dfn">作用域</em> 定义了一个代码块中名称的可见性。 如果代码块中定义了一个局部变量,则其作用域包含该代码块。 如果定义发生于函数代码块中,则其作用域会扩展到该函数所包含的任何代码块,除非有某个被包含代码块引入了对该名称的不同绑定。</p>
<p id="index-8">当一个名称在代码块中被使用时,会由包含它的最近作用域来解析。 对一个代码块可见的所有这种作用域的集合称为该代码块的 <em class="dfn">环境</em></p>
<p id="index-9">当一个名称完全找不到时,将会引发 <a class="reference internal" href="../library/exceptions.html#NameError" title="NameError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NameError</span></code></a> 异常。 如果当前作用域为函数作用域,且该名称指向一个局部变量,而此变量在该名称被使用的时候尚未绑定到特定值,将会引发 <a class="reference internal" href="../library/exceptions.html#UnboundLocalError" title="UnboundLocalError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">UnboundLocalError</span></code></a> 异常。 <a class="reference internal" href="../library/exceptions.html#UnboundLocalError" title="UnboundLocalError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">UnboundLocalError</span></code></a><a class="reference internal" href="../library/exceptions.html#NameError" title="NameError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NameError</span></code></a> 的一个子类。</p>
<p>如果一个代码块内的任何位置发生名称绑定操作,则代码块内所有对该名称的使用会被认为是对当前代码块的引用。 当一个名称在其被绑定前就在代码块内被使用时则会导致错误。 这个一个很微妙的规则。 Python 缺少声明语法,并允许名称绑定操作发生于代码块内的任何位置。 一个代码块的局部变量可通过在整个代码块文本中扫描名称绑定操作来确定。</p>
<p>如果 <a class="reference internal" href="simple_stmts.html#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> 语句出现在一个代码块中,则所有对该语句所指定名称的使用都是在最高层级命名空间内对该名称绑定的引用。 名称在最高层级命名内的解析是通过全局命名空间,也就是包含该代码块的模块的命名空间,以及内置命名空间即 <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a> 模块的命名空间。 全局命名空间会先被搜索。 如果未在其中找到指定名称,再搜索内置命名空间。 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句必须位于所有对其所指定名称的使用之前。</p>
<p><a class="reference internal" href="simple_stmts.html#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> 语句与同一代码块中名称绑定具有相同的作用域。 如果一个自由变量的最近包含作用域中有一条 global 语句,则该自由变量也会被当作是全局变量。</p>
<p><a class="reference internal" href="simple_stmts.html#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> 语句会使得相应的名称指向之前在最近包含函数作用域中绑定的变量。 如果指定名称不存在于任何包含函数作用域中则将在编译时引发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a></p>
<p id="index-10">模块的作用域会在模块第一次被导入时自动创建。 一个脚本的主模块总是被命名为 <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a></p>
<p>类定义代码块以及传给 <a class="reference internal" href="../library/functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a><a class="reference internal" href="../library/functions.html#eval" title="eval"><code class="xref py py-func docutils literal notranslate"><span class="pre">eval()</span></code></a> 的参数是名称解析上下文中的特殊情况。 类定义是可能使用并定义名称的可执行语句。 这些引用遵循正常的名称解析规则,例外之处在于未绑定的局部变量将会在全局命名空间中查找。 类定义的命名空间会成为该类的属性字典。 在类代码块中定义的名称的作用域会被限制在类代码块中;它不会扩展到方法的代码块中 -- 这也包括推导式和生成器表达式,因为它们都是使用函数作用域实现的。 这意味着以下代码将会失败:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">A</span><span class="p">:</span>
<span class="n">a</span> <span class="o">=</span> <span class="mi">42</span>
<span class="n">b</span> <span class="o">=</span> <span class="nb">list</span><span class="p">(</span><span class="n">a</span> <span class="o">+</span> <span class="n">i</span> <span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">10</span><span class="p">))</span>
</pre></div>
</div>
</section>
<section id="builtins-and-restricted-execution">
<span id="restrict-exec"></span><h3><span class="section-number">4.2.3. </span>内置命名空间和受限的执行<a class="headerlink" href="#builtins-and-restricted-execution" title="永久链接至标题"></a></h3>
<div class="impl-detail compound" id="index-11">
<p><strong>CPython implementation detail:</strong> 用户不应该接触 <code class="docutils literal notranslate"><span class="pre">__builtins__</span></code>,严格说来它属于实现细节。 用户如果要重载内置命名空间中的值则应该 <a class="reference internal" href="simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a> 并相应地修改该模块中的属性。</p>
</div>
<p>与一个代码块的执行相关联的内置命名空间实际上是通过在其全局命名空间中搜索名称 <code class="docutils literal notranslate"><span class="pre">__builtins__</span></code> 来找到的;这应该是一个字典或一个模块(在后一种情况下会使用该模块的字典)。 默认情况下,当在 <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a> 模块中时,<code class="docutils literal notranslate"><span class="pre">__builtins__</span></code> 就是内置模块 <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a>;当在任何其他模块中时,<code class="docutils literal notranslate"><span class="pre">__builtins__</span></code> 则是 <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a> 模块自身的字典的一个别名。</p>
</section>
<section id="interaction-with-dynamic-features">
<span id="dynamic-features"></span><h3><span class="section-number">4.2.4. </span>与动态特性的交互<a class="headerlink" href="#interaction-with-dynamic-features" title="永久链接至标题"></a></h3>
<p>自由变量的名称解析发生于运行时而不是编译时。 这意味着以下代码将打印出 42:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">i</span> <span class="o">=</span> <span class="mi">10</span>
<span class="k">def</span> <span class="nf">f</span><span class="p">():</span>
<span class="nb">print</span><span class="p">(</span><span class="n">i</span><span class="p">)</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">42</span>
<span class="n">f</span><span class="p">()</span>
</pre></div>
</div>
<p><a class="reference internal" href="../library/functions.html#eval" title="eval"><code class="xref py py-func docutils literal notranslate"><span class="pre">eval()</span></code></a><a class="reference internal" href="../library/functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a> 函数没有对完整环境的访问权限来解析名称。 名称可以在调用者的局部和全局命名空间中被解析。 自由变量的解析不是在最近包含命名空间中,而是在全局命名空间中。 <a class="footnote-reference brackets" href="#id3" id="id1">1</a> <a class="reference internal" href="../library/functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a><a class="reference internal" href="../library/functions.html#eval" title="eval"><code class="xref py py-func docutils literal notranslate"><span class="pre">eval()</span></code></a> 函数有可选参数用来重载全局和局部命名空间。 如果只指定一个命名空间,则它会同时作用于两者。</p>
</section>
</section>
<section id="exceptions">
<span id="id2"></span><h2><span class="section-number">4.3. </span>异常<a class="headerlink" href="#exceptions" title="永久链接至标题"></a></h2>
<span class="target" id="index-12"></span><p id="index-13">异常是中断代码块的正常控制流程以便处理错误或其他异常条件的一种方式。 异常会在错误被检测到的位置 <em>引发</em>,它可以被当前包围代码块或是任何直接或间接发起调用发生错误的代码块的其他代码块所 <em>处理</em></p>
<p>Python 解析器会在检测到运行时错误(例如零作为被除数)的时候引发异常。 Python 程序也可以通过 <a class="reference internal" href="simple_stmts.html#raise"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code></a> 语句显式地引发异常。 异常处理是通过 <a class="reference internal" href="compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> ... <a class="reference internal" href="compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 语句来指定的。 该语句的 <a class="reference internal" href="compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句可被用来指定清理代码,它并不处理异常,而是无论之前的代码是否发生异常都会被执行。</p>
<p id="index-14">Python 的错误处理采用的是“终止”模型:异常处理器可以找出发生了什么问题,并在外层继续执行,但它不能修复错误的根源并重试失败的操作(除非通过从顶层重新进入出错的代码片段)。</p>
<p id="index-15">当一个异常完全未被处理时,解释器会终止程序的执行,或者返回交互模式的主循环。 无论是哪种情况,它都会打印栈回溯信息,除非是当异常为 <a class="reference internal" href="../library/exceptions.html#SystemExit" title="SystemExit"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SystemExit</span></code></a> 的时候。</p>
<p>异常是通过类实例来标识的。 <a class="reference internal" href="compound_stmts.html#except"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">except</span></code></a> 子句会依据实例的类来选择:它必须引用实例的类或是其所属的基类。 实例可通过处理器被接收,并可携带有关异常条件的附加信息。</p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p>异常消息不是 Python API 的组成部分。 其内容可能在 Python 升级到新版本时不经警告地发生改变,不应该被需要在多版本解释器中运行的代码所依赖。</p>
</div>
<p>另请参看 <a class="reference internal" href="compound_stmts.html#try"><span class="std std-ref">try 语句</span></a> 小节中对 <a class="reference internal" href="compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句的描述以及 <a class="reference internal" href="simple_stmts.html#raise"><span class="std std-ref">raise 语句</span></a> 小节中对 <a class="reference internal" href="simple_stmts.html#raise"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code></a> 语句的描述。</p>
<p class="rubric">备注</p>
<dl class="footnote brackets">
<dt class="label" id="id3"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p>出现这样的限制是由于通过这些操作执行的代码在模块被编译的时候并不可用。</p>
</dd>
</dl>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">4. 执行模型</a><ul>
<li><a class="reference internal" href="#structure-of-a-program">4.1. 程序的结构</a></li>
<li><a class="reference internal" href="#naming-and-binding">4.2. 命名与绑定</a><ul>
<li><a class="reference internal" href="#binding-of-names">4.2.1. 名称的绑定</a></li>
<li><a class="reference internal" href="#resolution-of-names">4.2.2. 名称的解析</a></li>
<li><a class="reference internal" href="#builtins-and-restricted-execution">4.2.3. 内置命名空间和受限的执行</a></li>
<li><a class="reference internal" href="#interaction-with-dynamic-features">4.2.4. 与动态特性的交互</a></li>
</ul>
</li>
<li><a class="reference internal" href="#exceptions">4.3. 异常</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="datamodel.html"
title="上一章"><span class="section-number">3. </span>数据模型</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="import.html"
title="下一章"><span class="section-number">5. </span>导入系统</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/executionmodel.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="import.html" title="5. 导入系统"
>下一页</a> |</li>
<li class="right" >
<a href="datamodel.html" title="3. 数据模型"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,462 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>10. 完整的语法规范 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="Python 标准库" href="../library/index.html" />
<link rel="prev" title="9. 最高层级组件" href="toplevel_components.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/grammar.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h4>上一个主题</h4>
<p class="topless"><a href="toplevel_components.html"
title="上一章"><span class="section-number">9. </span>最高层级组件</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="../library/index.html"
title="下一章">Python 标准库</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/grammar.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/grammar.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="../library/index.html" title="Python 标准库"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="toplevel_components.html" title="9. 最高层级组件"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="full-grammar-specification">
<h1><span class="section-number">10. </span>完整的语法规范<a class="headerlink" href="#full-grammar-specification" title="永久链接至标题"></a></h1>
<p>这是完整的Python语法它被送入解析器生成器以生成解析Python源文件的解析器</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># Grammar for Python</span>
<span class="c1"># NOTE WELL: You should also follow all the steps listed at</span>
<span class="c1"># https://devguide.python.org/grammar/</span>
<span class="c1"># Start symbols for the grammar:</span>
<span class="c1"># single_input is a single interactive statement;</span>
<span class="c1"># file_input is a module or sequence of commands read from an input file;</span>
<span class="c1"># eval_input is the input for the eval() functions.</span>
<span class="c1"># func_type_input is a PEP 484 Python 2 function type comment</span>
<span class="c1"># NB: compound_stmt in single_input is followed by extra NEWLINE!</span>
<span class="c1"># NB: due to the way TYPE_COMMENT is tokenized it will always be followed by a NEWLINE</span>
<span class="n">single_input</span><span class="p">:</span> <span class="n">NEWLINE</span> <span class="o">|</span> <span class="n">simple_stmt</span> <span class="o">|</span> <span class="n">compound_stmt</span> <span class="n">NEWLINE</span>
<span class="n">file_input</span><span class="p">:</span> <span class="p">(</span><span class="n">NEWLINE</span> <span class="o">|</span> <span class="n">stmt</span><span class="p">)</span><span class="o">*</span> <span class="n">ENDMARKER</span>
<span class="n">eval_input</span><span class="p">:</span> <span class="n">testlist</span> <span class="n">NEWLINE</span><span class="o">*</span> <span class="n">ENDMARKER</span>
<span class="n">decorator</span><span class="p">:</span> <span class="s1">&#39;@&#39;</span> <span class="n">dotted_name</span> <span class="p">[</span> <span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">arglist</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span> <span class="p">]</span> <span class="n">NEWLINE</span>
<span class="n">decorators</span><span class="p">:</span> <span class="n">decorator</span><span class="o">+</span>
<span class="n">decorated</span><span class="p">:</span> <span class="n">decorators</span> <span class="p">(</span><span class="n">classdef</span> <span class="o">|</span> <span class="n">funcdef</span> <span class="o">|</span> <span class="n">async_funcdef</span><span class="p">)</span>
<span class="n">async_funcdef</span><span class="p">:</span> <span class="n">ASYNC</span> <span class="n">funcdef</span>
<span class="n">funcdef</span><span class="p">:</span> <span class="s1">&#39;def&#39;</span> <span class="n">NAME</span> <span class="n">parameters</span> <span class="p">[</span><span class="s1">&#39;-&gt;&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="s1">&#39;:&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">func_body_suite</span>
<span class="n">parameters</span><span class="p">:</span> <span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">typedargslist</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span>
<span class="c1"># The following definition for typedarglist is equivalent to this set of rules:</span>
<span class="c1">#</span>
<span class="c1"># arguments = argument (&#39;,&#39; [TYPE_COMMENT] argument)*</span>
<span class="c1"># argument = tfpdef [&#39;=&#39; test]</span>
<span class="c1"># kwargs = &#39;**&#39; tfpdef [&#39;,&#39;] [TYPE_COMMENT]</span>
<span class="c1"># args = &#39;*&#39; [tfpdef]</span>
<span class="c1"># kwonly_kwargs = (&#39;,&#39; [TYPE_COMMENT] argument)* (TYPE_COMMENT | [&#39;,&#39; [TYPE_COMMENT] [kwargs]])</span>
<span class="c1"># args_kwonly_kwargs = args kwonly_kwargs | kwargs</span>
<span class="c1"># poskeyword_args_kwonly_kwargs = arguments ( TYPE_COMMENT | [&#39;,&#39; [TYPE_COMMENT] [args_kwonly_kwargs]])</span>
<span class="c1"># typedargslist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs</span>
<span class="c1"># typedarglist = (arguments &#39;,&#39; [TYPE_COMMENT] &#39;/&#39; [&#39;,&#39; [[TYPE_COMMENT] typedargslist_no_posonly]])|(typedargslist_no_posonly)&quot;</span>
<span class="c1">#</span>
<span class="c1"># It needs to be fully expanded to allow our LL(1) parser to work on it.</span>
<span class="n">typedargslist</span><span class="p">:</span> <span class="p">(</span>
<span class="p">(</span><span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="s1">&#39;/&#39;</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="p">(</span>
<span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">(</span><span class="n">TYPE_COMMENT</span> <span class="o">|</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="p">[</span>
<span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">tfpdef</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">(</span><span class="n">TYPE_COMMENT</span> <span class="o">|</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]]])</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]]])</span>
<span class="o">|</span> <span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">tfpdef</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">(</span><span class="n">TYPE_COMMENT</span> <span class="o">|</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]]])</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]]]</span> <span class="p">)</span>
<span class="o">|</span> <span class="p">(</span><span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">(</span><span class="n">TYPE_COMMENT</span> <span class="o">|</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="p">[</span>
<span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">tfpdef</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">(</span><span class="n">TYPE_COMMENT</span> <span class="o">|</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]]])</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]]])</span>
<span class="o">|</span> <span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">tfpdef</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">(</span><span class="n">TYPE_COMMENT</span> <span class="o">|</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]]])</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">tfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">])</span>
<span class="p">)</span>
<span class="n">tfpdef</span><span class="p">:</span> <span class="n">NAME</span> <span class="p">[</span><span class="s1">&#39;:&#39;</span> <span class="n">test</span><span class="p">]</span>
<span class="c1"># The following definition for varargslist is equivalent to this set of rules:</span>
<span class="c1">#</span>
<span class="c1"># arguments = argument (&#39;,&#39; argument )*</span>
<span class="c1"># argument = vfpdef [&#39;=&#39; test]</span>
<span class="c1"># kwargs = &#39;**&#39; vfpdef [&#39;,&#39;]</span>
<span class="c1"># args = &#39;*&#39; [vfpdef]</span>
<span class="c1"># kwonly_kwargs = (&#39;,&#39; argument )* [&#39;,&#39; [kwargs]]</span>
<span class="c1"># args_kwonly_kwargs = args kwonly_kwargs | kwargs</span>
<span class="c1"># poskeyword_args_kwonly_kwargs = arguments [&#39;,&#39; [args_kwonly_kwargs]]</span>
<span class="c1"># vararglist_no_posonly = poskeyword_args_kwonly_kwargs | args_kwonly_kwargs</span>
<span class="c1"># varargslist = arguments &#39;,&#39; &#39;/&#39; [&#39;,&#39;[(vararglist_no_posonly)]] | (vararglist_no_posonly)</span>
<span class="c1">#</span>
<span class="c1"># It needs to be fully expanded to allow our LL(1) parser to work on it.</span>
<span class="n">varargslist</span><span class="p">:</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span> <span class="p">](</span><span class="s1">&#39;,&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="s1">&#39;,&#39;</span> <span class="s1">&#39;/&#39;</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span> <span class="p">(</span><span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span>
<span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">vfpdef</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]]]</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]]]</span>
<span class="o">|</span> <span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">vfpdef</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]]]</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">])</span> <span class="p">]]</span> <span class="o">|</span> <span class="p">(</span><span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span>
<span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">vfpdef</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]]]</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]]]</span>
<span class="o">|</span> <span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">vfpdef</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="n">test</span><span class="p">])</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]]]</span>
<span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">vfpdef</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span>
<span class="p">)</span>
<span class="n">vfpdef</span><span class="p">:</span> <span class="n">NAME</span>
<span class="n">stmt</span><span class="p">:</span> <span class="n">simple_stmt</span> <span class="o">|</span> <span class="n">compound_stmt</span>
<span class="n">simple_stmt</span><span class="p">:</span> <span class="n">small_stmt</span> <span class="p">(</span><span class="s1">&#39;;&#39;</span> <span class="n">small_stmt</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;;&#39;</span><span class="p">]</span> <span class="n">NEWLINE</span>
<span class="n">small_stmt</span><span class="p">:</span> <span class="p">(</span><span class="n">expr_stmt</span> <span class="o">|</span> <span class="n">del_stmt</span> <span class="o">|</span> <span class="n">pass_stmt</span> <span class="o">|</span> <span class="n">flow_stmt</span> <span class="o">|</span>
<span class="n">import_stmt</span> <span class="o">|</span> <span class="n">global_stmt</span> <span class="o">|</span> <span class="n">nonlocal_stmt</span> <span class="o">|</span> <span class="n">assert_stmt</span><span class="p">)</span>
<span class="n">expr_stmt</span><span class="p">:</span> <span class="n">testlist_star_expr</span> <span class="p">(</span><span class="n">annassign</span> <span class="o">|</span> <span class="n">augassign</span> <span class="p">(</span><span class="n">yield_expr</span><span class="o">|</span><span class="n">testlist</span><span class="p">)</span> <span class="o">|</span>
<span class="p">[(</span><span class="s1">&#39;=&#39;</span> <span class="p">(</span><span class="n">yield_expr</span><span class="o">|</span><span class="n">testlist_star_expr</span><span class="p">))</span><span class="o">+</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]]</span> <span class="p">)</span>
<span class="n">annassign</span><span class="p">:</span> <span class="s1">&#39;:&#39;</span> <span class="n">test</span> <span class="p">[</span><span class="s1">&#39;=&#39;</span> <span class="p">(</span><span class="n">yield_expr</span><span class="o">|</span><span class="n">testlist_star_expr</span><span class="p">)]</span>
<span class="n">testlist_star_expr</span><span class="p">:</span> <span class="p">(</span><span class="n">test</span><span class="o">|</span><span class="n">star_expr</span><span class="p">)</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">(</span><span class="n">test</span><span class="o">|</span><span class="n">star_expr</span><span class="p">))</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span>
<span class="n">augassign</span><span class="p">:</span> <span class="p">(</span><span class="s1">&#39;+=&#39;</span> <span class="o">|</span> <span class="s1">&#39;-=&#39;</span> <span class="o">|</span> <span class="s1">&#39;*=&#39;</span> <span class="o">|</span> <span class="s1">&#39;@=&#39;</span> <span class="o">|</span> <span class="s1">&#39;/=&#39;</span> <span class="o">|</span> <span class="s1">&#39;%=&#39;</span> <span class="o">|</span> <span class="s1">&#39;&amp;=&#39;</span> <span class="o">|</span> <span class="s1">&#39;|=&#39;</span> <span class="o">|</span> <span class="s1">&#39;^=&#39;</span> <span class="o">|</span>
<span class="s1">&#39;&lt;&lt;=&#39;</span> <span class="o">|</span> <span class="s1">&#39;&gt;&gt;=&#39;</span> <span class="o">|</span> <span class="s1">&#39;**=&#39;</span> <span class="o">|</span> <span class="s1">&#39;//=&#39;</span><span class="p">)</span>
<span class="c1"># For normal and annotated assignments, additional restrictions enforced by the interpreter</span>
<span class="n">del_stmt</span><span class="p">:</span> <span class="s1">&#39;del&#39;</span> <span class="n">exprlist</span>
<span class="n">pass_stmt</span><span class="p">:</span> <span class="s1">&#39;pass&#39;</span>
<span class="n">flow_stmt</span><span class="p">:</span> <span class="n">break_stmt</span> <span class="o">|</span> <span class="n">continue_stmt</span> <span class="o">|</span> <span class="n">return_stmt</span> <span class="o">|</span> <span class="n">raise_stmt</span> <span class="o">|</span> <span class="n">yield_stmt</span>
<span class="n">break_stmt</span><span class="p">:</span> <span class="s1">&#39;break&#39;</span>
<span class="n">continue_stmt</span><span class="p">:</span> <span class="s1">&#39;continue&#39;</span>
<span class="n">return_stmt</span><span class="p">:</span> <span class="s1">&#39;return&#39;</span> <span class="p">[</span><span class="n">testlist_star_expr</span><span class="p">]</span>
<span class="n">yield_stmt</span><span class="p">:</span> <span class="n">yield_expr</span>
<span class="n">raise_stmt</span><span class="p">:</span> <span class="s1">&#39;raise&#39;</span> <span class="p">[</span><span class="n">test</span> <span class="p">[</span><span class="s1">&#39;from&#39;</span> <span class="n">test</span><span class="p">]]</span>
<span class="n">import_stmt</span><span class="p">:</span> <span class="n">import_name</span> <span class="o">|</span> <span class="n">import_from</span>
<span class="n">import_name</span><span class="p">:</span> <span class="s1">&#39;import&#39;</span> <span class="n">dotted_as_names</span>
<span class="c1"># note below: the (&#39;.&#39; | &#39;...&#39;) is necessary because &#39;...&#39; is tokenized as ELLIPSIS</span>
<span class="n">import_from</span><span class="p">:</span> <span class="p">(</span><span class="s1">&#39;from&#39;</span> <span class="p">((</span><span class="s1">&#39;.&#39;</span> <span class="o">|</span> <span class="s1">&#39;...&#39;</span><span class="p">)</span><span class="o">*</span> <span class="n">dotted_name</span> <span class="o">|</span> <span class="p">(</span><span class="s1">&#39;.&#39;</span> <span class="o">|</span> <span class="s1">&#39;...&#39;</span><span class="p">)</span><span class="o">+</span><span class="p">)</span>
<span class="s1">&#39;import&#39;</span> <span class="p">(</span><span class="s1">&#39;*&#39;</span> <span class="o">|</span> <span class="s1">&#39;(&#39;</span> <span class="n">import_as_names</span> <span class="s1">&#39;)&#39;</span> <span class="o">|</span> <span class="n">import_as_names</span><span class="p">))</span>
<span class="n">import_as_name</span><span class="p">:</span> <span class="n">NAME</span> <span class="p">[</span><span class="s1">&#39;as&#39;</span> <span class="n">NAME</span><span class="p">]</span>
<span class="n">dotted_as_name</span><span class="p">:</span> <span class="n">dotted_name</span> <span class="p">[</span><span class="s1">&#39;as&#39;</span> <span class="n">NAME</span><span class="p">]</span>
<span class="n">import_as_names</span><span class="p">:</span> <span class="n">import_as_name</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">import_as_name</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span>
<span class="n">dotted_as_names</span><span class="p">:</span> <span class="n">dotted_as_name</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">dotted_as_name</span><span class="p">)</span><span class="o">*</span>
<span class="n">dotted_name</span><span class="p">:</span> <span class="n">NAME</span> <span class="p">(</span><span class="s1">&#39;.&#39;</span> <span class="n">NAME</span><span class="p">)</span><span class="o">*</span>
<span class="n">global_stmt</span><span class="p">:</span> <span class="s1">&#39;global&#39;</span> <span class="n">NAME</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">NAME</span><span class="p">)</span><span class="o">*</span>
<span class="n">nonlocal_stmt</span><span class="p">:</span> <span class="s1">&#39;nonlocal&#39;</span> <span class="n">NAME</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">NAME</span><span class="p">)</span><span class="o">*</span>
<span class="n">assert_stmt</span><span class="p">:</span> <span class="s1">&#39;assert&#39;</span> <span class="n">test</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="n">test</span><span class="p">]</span>
<span class="n">compound_stmt</span><span class="p">:</span> <span class="n">if_stmt</span> <span class="o">|</span> <span class="n">while_stmt</span> <span class="o">|</span> <span class="n">for_stmt</span> <span class="o">|</span> <span class="n">try_stmt</span> <span class="o">|</span> <span class="n">with_stmt</span> <span class="o">|</span> <span class="n">funcdef</span> <span class="o">|</span> <span class="n">classdef</span> <span class="o">|</span> <span class="n">decorated</span> <span class="o">|</span> <span class="n">async_stmt</span>
<span class="n">async_stmt</span><span class="p">:</span> <span class="n">ASYNC</span> <span class="p">(</span><span class="n">funcdef</span> <span class="o">|</span> <span class="n">with_stmt</span> <span class="o">|</span> <span class="n">for_stmt</span><span class="p">)</span>
<span class="n">if_stmt</span><span class="p">:</span> <span class="s1">&#39;if&#39;</span> <span class="n">namedexpr_test</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span> <span class="p">(</span><span class="s1">&#39;elif&#39;</span> <span class="n">namedexpr_test</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;else&#39;</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span><span class="p">]</span>
<span class="n">while_stmt</span><span class="p">:</span> <span class="s1">&#39;while&#39;</span> <span class="n">namedexpr_test</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span> <span class="p">[</span><span class="s1">&#39;else&#39;</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span><span class="p">]</span>
<span class="n">for_stmt</span><span class="p">:</span> <span class="s1">&#39;for&#39;</span> <span class="n">exprlist</span> <span class="s1">&#39;in&#39;</span> <span class="n">testlist</span> <span class="s1">&#39;:&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">suite</span> <span class="p">[</span><span class="s1">&#39;else&#39;</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span><span class="p">]</span>
<span class="n">try_stmt</span><span class="p">:</span> <span class="p">(</span><span class="s1">&#39;try&#39;</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span>
<span class="p">((</span><span class="n">except_clause</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span><span class="p">)</span><span class="o">+</span>
<span class="p">[</span><span class="s1">&#39;else&#39;</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span><span class="p">]</span>
<span class="p">[</span><span class="s1">&#39;finally&#39;</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span><span class="p">]</span> <span class="o">|</span>
<span class="s1">&#39;finally&#39;</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span><span class="p">))</span>
<span class="n">with_stmt</span><span class="p">:</span> <span class="s1">&#39;with&#39;</span> <span class="n">with_item</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">with_item</span><span class="p">)</span><span class="o">*</span> <span class="s1">&#39;:&#39;</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span><span class="p">]</span> <span class="n">suite</span>
<span class="n">with_item</span><span class="p">:</span> <span class="n">test</span> <span class="p">[</span><span class="s1">&#39;as&#39;</span> <span class="n">expr</span><span class="p">]</span>
<span class="c1"># NB compile.c makes sure that the default except clause is last</span>
<span class="n">except_clause</span><span class="p">:</span> <span class="s1">&#39;except&#39;</span> <span class="p">[</span><span class="n">test</span> <span class="p">[</span><span class="s1">&#39;as&#39;</span> <span class="n">NAME</span><span class="p">]]</span>
<span class="n">suite</span><span class="p">:</span> <span class="n">simple_stmt</span> <span class="o">|</span> <span class="n">NEWLINE</span> <span class="n">INDENT</span> <span class="n">stmt</span><span class="o">+</span> <span class="n">DEDENT</span>
<span class="n">namedexpr_test</span><span class="p">:</span> <span class="n">test</span> <span class="p">[</span><span class="s1">&#39;:=&#39;</span> <span class="n">test</span><span class="p">]</span>
<span class="n">test</span><span class="p">:</span> <span class="n">or_test</span> <span class="p">[</span><span class="s1">&#39;if&#39;</span> <span class="n">or_test</span> <span class="s1">&#39;else&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="o">|</span> <span class="n">lambdef</span>
<span class="n">test_nocond</span><span class="p">:</span> <span class="n">or_test</span> <span class="o">|</span> <span class="n">lambdef_nocond</span>
<span class="n">lambdef</span><span class="p">:</span> <span class="s1">&#39;lambda&#39;</span> <span class="p">[</span><span class="n">varargslist</span><span class="p">]</span> <span class="s1">&#39;:&#39;</span> <span class="n">test</span>
<span class="n">lambdef_nocond</span><span class="p">:</span> <span class="s1">&#39;lambda&#39;</span> <span class="p">[</span><span class="n">varargslist</span><span class="p">]</span> <span class="s1">&#39;:&#39;</span> <span class="n">test_nocond</span>
<span class="n">or_test</span><span class="p">:</span> <span class="n">and_test</span> <span class="p">(</span><span class="s1">&#39;or&#39;</span> <span class="n">and_test</span><span class="p">)</span><span class="o">*</span>
<span class="n">and_test</span><span class="p">:</span> <span class="n">not_test</span> <span class="p">(</span><span class="s1">&#39;and&#39;</span> <span class="n">not_test</span><span class="p">)</span><span class="o">*</span>
<span class="n">not_test</span><span class="p">:</span> <span class="s1">&#39;not&#39;</span> <span class="n">not_test</span> <span class="o">|</span> <span class="n">comparison</span>
<span class="n">comparison</span><span class="p">:</span> <span class="n">expr</span> <span class="p">(</span><span class="n">comp_op</span> <span class="n">expr</span><span class="p">)</span><span class="o">*</span>
<span class="c1"># &lt;&gt; isn&#39;t actually a valid comparison operator in Python. It&#39;s here for the</span>
<span class="c1"># sake of a __future__ import described in PEP 401 (which really works :-)</span>
<span class="n">comp_op</span><span class="p">:</span> <span class="s1">&#39;&lt;&#39;</span><span class="o">|</span><span class="s1">&#39;&gt;&#39;</span><span class="o">|</span><span class="s1">&#39;==&#39;</span><span class="o">|</span><span class="s1">&#39;&gt;=&#39;</span><span class="o">|</span><span class="s1">&#39;&lt;=&#39;</span><span class="o">|</span><span class="s1">&#39;&lt;&gt;&#39;</span><span class="o">|</span><span class="s1">&#39;!=&#39;</span><span class="o">|</span><span class="s1">&#39;in&#39;</span><span class="o">|</span><span class="s1">&#39;not&#39;</span> <span class="s1">&#39;in&#39;</span><span class="o">|</span><span class="s1">&#39;is&#39;</span><span class="o">|</span><span class="s1">&#39;is&#39;</span> <span class="s1">&#39;not&#39;</span>
<span class="n">star_expr</span><span class="p">:</span> <span class="s1">&#39;*&#39;</span> <span class="n">expr</span>
<span class="n">expr</span><span class="p">:</span> <span class="n">xor_expr</span> <span class="p">(</span><span class="s1">&#39;|&#39;</span> <span class="n">xor_expr</span><span class="p">)</span><span class="o">*</span>
<span class="n">xor_expr</span><span class="p">:</span> <span class="n">and_expr</span> <span class="p">(</span><span class="s1">&#39;^&#39;</span> <span class="n">and_expr</span><span class="p">)</span><span class="o">*</span>
<span class="n">and_expr</span><span class="p">:</span> <span class="n">shift_expr</span> <span class="p">(</span><span class="s1">&#39;&amp;&#39;</span> <span class="n">shift_expr</span><span class="p">)</span><span class="o">*</span>
<span class="n">shift_expr</span><span class="p">:</span> <span class="n">arith_expr</span> <span class="p">((</span><span class="s1">&#39;&lt;&lt;&#39;</span><span class="o">|</span><span class="s1">&#39;&gt;&gt;&#39;</span><span class="p">)</span> <span class="n">arith_expr</span><span class="p">)</span><span class="o">*</span>
<span class="n">arith_expr</span><span class="p">:</span> <span class="n">term</span> <span class="p">((</span><span class="s1">&#39;+&#39;</span><span class="o">|</span><span class="s1">&#39;-&#39;</span><span class="p">)</span> <span class="n">term</span><span class="p">)</span><span class="o">*</span>
<span class="n">term</span><span class="p">:</span> <span class="n">factor</span> <span class="p">((</span><span class="s1">&#39;*&#39;</span><span class="o">|</span><span class="s1">&#39;@&#39;</span><span class="o">|</span><span class="s1">&#39;/&#39;</span><span class="o">|</span><span class="s1">&#39;%&#39;</span><span class="o">|</span><span class="s1">&#39;//&#39;</span><span class="p">)</span> <span class="n">factor</span><span class="p">)</span><span class="o">*</span>
<span class="n">factor</span><span class="p">:</span> <span class="p">(</span><span class="s1">&#39;+&#39;</span><span class="o">|</span><span class="s1">&#39;-&#39;</span><span class="o">|</span><span class="s1">&#39;~&#39;</span><span class="p">)</span> <span class="n">factor</span> <span class="o">|</span> <span class="n">power</span>
<span class="n">power</span><span class="p">:</span> <span class="n">atom_expr</span> <span class="p">[</span><span class="s1">&#39;**&#39;</span> <span class="n">factor</span><span class="p">]</span>
<span class="n">atom_expr</span><span class="p">:</span> <span class="p">[</span><span class="n">AWAIT</span><span class="p">]</span> <span class="n">atom</span> <span class="n">trailer</span><span class="o">*</span>
<span class="n">atom</span><span class="p">:</span> <span class="p">(</span><span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">yield_expr</span><span class="o">|</span><span class="n">testlist_comp</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span> <span class="o">|</span>
<span class="s1">&#39;[&#39;</span> <span class="p">[</span><span class="n">testlist_comp</span><span class="p">]</span> <span class="s1">&#39;]&#39;</span> <span class="o">|</span>
<span class="s1">&#39;{&#39;</span> <span class="p">[</span><span class="n">dictorsetmaker</span><span class="p">]</span> <span class="s1">&#39;}&#39;</span> <span class="o">|</span>
<span class="n">NAME</span> <span class="o">|</span> <span class="n">NUMBER</span> <span class="o">|</span> <span class="n">STRING</span><span class="o">+</span> <span class="o">|</span> <span class="s1">&#39;...&#39;</span> <span class="o">|</span> <span class="s1">&#39;None&#39;</span> <span class="o">|</span> <span class="s1">&#39;True&#39;</span> <span class="o">|</span> <span class="s1">&#39;False&#39;</span><span class="p">)</span>
<span class="n">testlist_comp</span><span class="p">:</span> <span class="p">(</span><span class="n">namedexpr_test</span><span class="o">|</span><span class="n">star_expr</span><span class="p">)</span> <span class="p">(</span> <span class="n">comp_for</span> <span class="o">|</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">(</span><span class="n">namedexpr_test</span><span class="o">|</span><span class="n">star_expr</span><span class="p">))</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span> <span class="p">)</span>
<span class="n">trailer</span><span class="p">:</span> <span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">arglist</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span> <span class="o">|</span> <span class="s1">&#39;[&#39;</span> <span class="n">subscriptlist</span> <span class="s1">&#39;]&#39;</span> <span class="o">|</span> <span class="s1">&#39;.&#39;</span> <span class="n">NAME</span>
<span class="n">subscriptlist</span><span class="p">:</span> <span class="n">subscript</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">subscript</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span>
<span class="n">subscript</span><span class="p">:</span> <span class="n">test</span> <span class="o">|</span> <span class="p">[</span><span class="n">test</span><span class="p">]</span> <span class="s1">&#39;:&#39;</span> <span class="p">[</span><span class="n">test</span><span class="p">]</span> <span class="p">[</span><span class="n">sliceop</span><span class="p">]</span>
<span class="n">sliceop</span><span class="p">:</span> <span class="s1">&#39;:&#39;</span> <span class="p">[</span><span class="n">test</span><span class="p">]</span>
<span class="n">exprlist</span><span class="p">:</span> <span class="p">(</span><span class="n">expr</span><span class="o">|</span><span class="n">star_expr</span><span class="p">)</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">(</span><span class="n">expr</span><span class="o">|</span><span class="n">star_expr</span><span class="p">))</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span>
<span class="n">testlist</span><span class="p">:</span> <span class="n">test</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">test</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span>
<span class="n">dictorsetmaker</span><span class="p">:</span> <span class="p">(</span> <span class="p">((</span><span class="n">test</span> <span class="s1">&#39;:&#39;</span> <span class="n">test</span> <span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">expr</span><span class="p">)</span>
<span class="p">(</span><span class="n">comp_for</span> <span class="o">|</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">(</span><span class="n">test</span> <span class="s1">&#39;:&#39;</span> <span class="n">test</span> <span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">expr</span><span class="p">))</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]))</span> <span class="o">|</span>
<span class="p">((</span><span class="n">test</span> <span class="o">|</span> <span class="n">star_expr</span><span class="p">)</span>
<span class="p">(</span><span class="n">comp_for</span> <span class="o">|</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="p">(</span><span class="n">test</span> <span class="o">|</span> <span class="n">star_expr</span><span class="p">))</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]))</span> <span class="p">)</span>
<span class="n">classdef</span><span class="p">:</span> <span class="s1">&#39;class&#39;</span> <span class="n">NAME</span> <span class="p">[</span><span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">arglist</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span><span class="p">]</span> <span class="s1">&#39;:&#39;</span> <span class="n">suite</span>
<span class="n">arglist</span><span class="p">:</span> <span class="n">argument</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">argument</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span><span class="p">]</span>
<span class="c1"># The reason that keywords are test nodes instead of NAME is that using NAME</span>
<span class="c1"># results in an ambiguity. ast.c makes sure it&#39;s a NAME.</span>
<span class="c1"># &quot;test &#39;=&#39; test&quot; is really &quot;keyword &#39;=&#39; test&quot;, but we have no such token.</span>
<span class="c1"># These need to be in a single rule to avoid grammar that is ambiguous</span>
<span class="c1"># to our LL(1) parser. Even though &#39;test&#39; includes &#39;*expr&#39; in star_expr,</span>
<span class="c1"># we explicitly match &#39;*&#39; here, too, to give it proper precedence.</span>
<span class="c1"># Illegal combinations and orderings are blocked in ast.c:</span>
<span class="c1"># multiple (test comp_for) arguments are blocked; keyword unpackings</span>
<span class="c1"># that precede iterable unpackings are blocked; etc.</span>
<span class="n">argument</span><span class="p">:</span> <span class="p">(</span> <span class="n">test</span> <span class="p">[</span><span class="n">comp_for</span><span class="p">]</span> <span class="o">|</span>
<span class="n">test</span> <span class="s1">&#39;:=&#39;</span> <span class="n">test</span> <span class="o">|</span>
<span class="n">test</span> <span class="s1">&#39;=&#39;</span> <span class="n">test</span> <span class="o">|</span>
<span class="s1">&#39;**&#39;</span> <span class="n">test</span> <span class="o">|</span>
<span class="s1">&#39;*&#39;</span> <span class="n">test</span> <span class="p">)</span>
<span class="n">comp_iter</span><span class="p">:</span> <span class="n">comp_for</span> <span class="o">|</span> <span class="n">comp_if</span>
<span class="n">sync_comp_for</span><span class="p">:</span> <span class="s1">&#39;for&#39;</span> <span class="n">exprlist</span> <span class="s1">&#39;in&#39;</span> <span class="n">or_test</span> <span class="p">[</span><span class="n">comp_iter</span><span class="p">]</span>
<span class="n">comp_for</span><span class="p">:</span> <span class="p">[</span><span class="n">ASYNC</span><span class="p">]</span> <span class="n">sync_comp_for</span>
<span class="n">comp_if</span><span class="p">:</span> <span class="s1">&#39;if&#39;</span> <span class="n">test_nocond</span> <span class="p">[</span><span class="n">comp_iter</span><span class="p">]</span>
<span class="c1"># not used in grammar, but may appear in &quot;node&quot; passed from Parser to Compiler</span>
<span class="n">encoding_decl</span><span class="p">:</span> <span class="n">NAME</span>
<span class="n">yield_expr</span><span class="p">:</span> <span class="s1">&#39;yield&#39;</span> <span class="p">[</span><span class="n">yield_arg</span><span class="p">]</span>
<span class="n">yield_arg</span><span class="p">:</span> <span class="s1">&#39;from&#39;</span> <span class="n">test</span> <span class="o">|</span> <span class="n">testlist_star_expr</span>
<span class="c1"># the TYPE_COMMENT in suites is only parsed for funcdefs,</span>
<span class="c1"># but can&#39;t go elsewhere due to ambiguity</span>
<span class="n">func_body_suite</span><span class="p">:</span> <span class="n">simple_stmt</span> <span class="o">|</span> <span class="n">NEWLINE</span> <span class="p">[</span><span class="n">TYPE_COMMENT</span> <span class="n">NEWLINE</span><span class="p">]</span> <span class="n">INDENT</span> <span class="n">stmt</span><span class="o">+</span> <span class="n">DEDENT</span>
<span class="n">func_type_input</span><span class="p">:</span> <span class="n">func_type</span> <span class="n">NEWLINE</span><span class="o">*</span> <span class="n">ENDMARKER</span>
<span class="n">func_type</span><span class="p">:</span> <span class="s1">&#39;(&#39;</span> <span class="p">[</span><span class="n">typelist</span><span class="p">]</span> <span class="s1">&#39;)&#39;</span> <span class="s1">&#39;-&gt;&#39;</span> <span class="n">test</span>
<span class="c1"># typelist is a modified typedargslist (see above)</span>
<span class="n">typelist</span><span class="p">:</span> <span class="p">(</span><span class="n">test</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">test</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span>
<span class="p">[</span><span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">test</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">test</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="s1">&#39;**&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">test</span><span class="p">]]</span>
<span class="o">|</span> <span class="s1">&#39;*&#39;</span> <span class="p">[</span><span class="n">test</span><span class="p">]</span> <span class="p">(</span><span class="s1">&#39;,&#39;</span> <span class="n">test</span><span class="p">)</span><span class="o">*</span> <span class="p">[</span><span class="s1">&#39;,&#39;</span> <span class="s1">&#39;**&#39;</span> <span class="n">test</span><span class="p">]</span> <span class="o">|</span> <span class="s1">&#39;**&#39;</span> <span class="n">test</span><span class="p">)</span>
</pre></div>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h4>上一个主题</h4>
<p class="topless"><a href="toplevel_components.html"
title="上一章"><span class="section-number">9. </span>最高层级组件</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="../library/index.html"
title="下一章">Python 标准库</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/grammar.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="../library/index.html" title="Python 标准库"
>下一页</a> |</li>
<li class="right" >
<a href="toplevel_components.html" title="9. 最高层级组件"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>

View File

@@ -0,0 +1,749 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>5. 导入系统 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="6. 表达式" href="expressions.html" />
<link rel="prev" title="4. 执行模型" href="executionmodel.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/import.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">5. 导入系统</a><ul>
<li><a class="reference internal" href="#importlib">5.1. <code class="xref py py-mod docutils literal notranslate"><span class="pre">importlib</span></code></a></li>
<li><a class="reference internal" href="#packages">5.2. 包</a><ul>
<li><a class="reference internal" href="#regular-packages">5.2.1. 常规包</a></li>
<li><a class="reference internal" href="#namespace-packages">5.2.2. 命名空间包</a></li>
</ul>
</li>
<li><a class="reference internal" href="#searching">5.3. 搜索</a><ul>
<li><a class="reference internal" href="#the-module-cache">5.3.1. 模块缓存</a></li>
<li><a class="reference internal" href="#finders-and-loaders">5.3.2. 查找器和加载器</a></li>
<li><a class="reference internal" href="#import-hooks">5.3.3. 导入钩子</a></li>
<li><a class="reference internal" href="#the-meta-path">5.3.4. 元路径</a></li>
</ul>
</li>
<li><a class="reference internal" href="#loading">5.4. 加载</a><ul>
<li><a class="reference internal" href="#loaders">5.4.1. 加载器</a></li>
<li><a class="reference internal" href="#submodules">5.4.2. 子模块</a></li>
<li><a class="reference internal" href="#module-spec">5.4.3. 模块规格说明</a></li>
<li><a class="reference internal" href="#import-related-module-attributes">5.4.4. 导入相关的模块属性</a></li>
<li><a class="reference internal" href="#module-path">5.4.5. module.__path__</a></li>
<li><a class="reference internal" href="#module-reprs">5.4.6. 模块的 repr</a></li>
<li><a class="reference internal" href="#cached-bytecode-invalidation">5.4.7. 已缓存字节码的失效</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-path-based-finder">5.5. 基于路径的查找器</a><ul>
<li><a class="reference internal" href="#path-entry-finders">5.5.1. 路径条目查找器</a></li>
<li><a class="reference internal" href="#path-entry-finder-protocol">5.5.2. 路径条目查找器协议</a></li>
</ul>
</li>
<li><a class="reference internal" href="#replacing-the-standard-import-system">5.6. 替换标准导入系统</a></li>
<li><a class="reference internal" href="#package-relative-imports">5.7. 包相对导入</a></li>
<li><a class="reference internal" href="#special-considerations-for-main">5.8. 有关 __main__ 的特殊事项</a><ul>
<li><a class="reference internal" href="#main-spec">5.8.1. __main__.__spec__</a></li>
</ul>
</li>
<li><a class="reference internal" href="#open-issues">5.9. 开放问题项</a></li>
<li><a class="reference internal" href="#references">5.10. 参考文献</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="executionmodel.html"
title="上一章"><span class="section-number">4. </span>执行模型</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="expressions.html"
title="下一章"><span class="section-number">6. </span>表达式</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/import.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/import.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="expressions.html" title="6. 表达式"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="executionmodel.html" title="4. 执行模型"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="the-import-system">
<span id="importsystem"></span><h1><span class="section-number">5. </span>导入系统<a class="headerlink" href="#the-import-system" title="永久链接至标题"></a></h1>
<p id="index-0">一个 <a class="reference internal" href="../glossary.html#term-module"><span class="xref std std-term">module</span></a> 内的 Python 代码通过 <a class="reference internal" href="../glossary.html#term-importing"><span class="xref std std-term">importing</span></a> 操作就能够访问另一个模块内的代码。 <a class="reference internal" href="simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句是发起调用导入机制的最常用方式,但不是唯一的方式。 <a class="reference internal" href="../library/importlib.html#importlib.import_module" title="importlib.import_module"><code class="xref py py-func docutils literal notranslate"><span class="pre">importlib.import_module()</span></code></a> 以及内置的 <a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 等函数也可以被用来发起调用导入机制。</p>
<p><a class="reference internal" href="simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句结合了两个操作;它先搜索指定名称的模块,然后将搜索结果绑定到当前作用域中的名称。 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code> 语句的搜索操作被定义为对 <a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 函数的调用并带有适当的参数。 <a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 的返回值会被用于执行 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code> 语句的名称绑定操作。 请参阅 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code> 语句了解名称绑定操作的更多细节。</p>
<p><a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 的直接调用将仅执行模块搜索以及在找到时的模块创建操作。 不过也可能产生某些副作用,例如导入父包和更新各种缓存 (包括 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a>),只有 <a class="reference internal" href="simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句会执行名称绑定操作。</p>
<p><a class="reference internal" href="simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句被执行时,标准的内置 <a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 函数会被调用。 其他发起调用导入系统的机制 (例如 <a class="reference internal" href="../library/importlib.html#importlib.import_module" title="importlib.import_module"><code class="xref py py-func docutils literal notranslate"><span class="pre">importlib.import_module()</span></code></a>) 可能会选择绕过 <a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 并使用它们自己的解决方案来实现导入机制。</p>
<p>当一个模块首次被导入时Python 会搜索该模块,如果找到就创建一个 module 对象 <a class="footnote-reference brackets" href="#fnmo" id="id1">1</a> 并初始化它。 如果指定名称的模块未找到,则会引发 <a class="reference internal" href="../library/exceptions.html#ModuleNotFoundError" title="ModuleNotFoundError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ModuleNotFoundError</span></code></a>。 当发起调用导入机制时Python 会实现多种策略来搜索指定名称的模块。 这些策略可以通过使用使用下文所描述的多种钩子来加以修改和扩展。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.3 版更改: </span>导入系统已被更新以完全实现 <span class="target" id="index-46"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0302"><strong>PEP 302</strong></a> 中的第二阶段要求。 不会再有任何隐式的导入机制 —— 整个导入系统都通过 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a> 暴露出来。 此外,对原生命名空间包的支持也已被实现 (参见 <span class="target" id="index-47"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0420"><strong>PEP 420</strong></a>)。</p>
</div>
<section id="importlib">
<h2><span class="section-number">5.1. </span><a class="reference internal" href="../library/importlib.html#module-importlib" title="importlib: The implementation of the import machinery."><code class="xref py py-mod docutils literal notranslate"><span class="pre">importlib</span></code></a><a class="headerlink" href="#importlib" title="永久链接至标题"></a></h2>
<p><a class="reference internal" href="../library/importlib.html#module-importlib" title="importlib: The implementation of the import machinery."><code class="xref py py-mod docutils literal notranslate"><span class="pre">importlib</span></code></a> 模块提供了一个丰富的 API 用来与导入系统进行交互。 例如 <a class="reference internal" href="../library/importlib.html#importlib.import_module" title="importlib.import_module"><code class="xref py py-func docutils literal notranslate"><span class="pre">importlib.import_module()</span></code></a> 提供了相比内置的 <a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 更推荐、更简单的 API 用来发起调用导入机制。 更多细节请参看 <a class="reference internal" href="../library/importlib.html#module-importlib" title="importlib: The implementation of the import machinery."><code class="xref py py-mod docutils literal notranslate"><span class="pre">importlib</span></code></a> 库文档。</p>
</section>
<section id="packages">
<h2><span class="section-number">5.2. </span><a class="headerlink" href="#packages" title="永久链接至标题"></a></h2>
<p id="index-3">Python 只有一种模块对象类型,所有模块都属于该类型,无论模块是用 Python、C 还是别的语言实现。 为了帮助组织模块并提供名称层次结构Python 还引入了 <a class="reference internal" href="../glossary.html#term-package"><span class="xref std std-term"></span></a> 的概念。</p>
<p>你可以把包看成是文件系统中的目录,并把模块看成是目录中的文件,但请不要对这个类比做过于字面的理解,因为包和模块不是必须来自于文件系统。 为了方便理解本文档,我们将继续使用这种目录和文件的类比。 与文件系统一样,包通过层次结构进行组织,在包之内除了一般的模块,还可以有子包。</p>
<p>要注意的一个重点概念是所有包都是模块,但并非所有模块都是包。 或者换句话说,包只是一种特殊的模块。 特别地,任何具有 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性的模块都会被当作是包。</p>
<p>所有模块都有自己的名字。 子包名与其父包名以点号分隔,与 Python 的标准属性访问语法一致。 例如你可能看到一个名为 <a class="reference internal" href="../library/sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sys</span></code></a> 的模块,以及一个名为 <a class="reference internal" href="../library/email.html#module-email" title="email: Package supporting the parsing, manipulating, and generating email messages."><code class="xref py py-mod docutils literal notranslate"><span class="pre">email</span></code></a> 的包,这个包又有一个名为 <a class="reference internal" href="../library/email.mime.html#module-email.mime" title="email.mime: Build MIME messages."><code class="xref py py-mod docutils literal notranslate"><span class="pre">email.mime</span></code></a> 的子包和该子包中的名为 <code class="xref py py-mod docutils literal notranslate"><span class="pre">email.mime.text</span></code> 的子包。</p>
<section id="regular-packages">
<h3><span class="section-number">5.2.1. </span>常规包<a class="headerlink" href="#regular-packages" title="永久链接至标题"></a></h3>
<p id="index-4">Python 定义了两种类型的包,<a class="reference internal" href="../glossary.html#term-regular-package"><span class="xref std std-term">常规包</span></a><a class="reference internal" href="../glossary.html#term-namespace-package"><span class="xref std std-term">命名空间包</span></a>。 常规包是传统的包类型,它们在 Python 3.2 及之前就已存在。 常规包通常以一个包含 <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> 文件的目录形式实现。 当一个常规包被导入时,这个 <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> 文件会隐式地被执行,它所定义的对象会被绑定到该包命名空间中的名称。<code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> 文件可以包含与任何其他模块中所包含的 Python 代码相似的代码Python 将在模块被导入时为其添加额外的属性。</p>
<p>例如,以下文件系统布局定义了一个最高层级的 <code class="docutils literal notranslate"><span class="pre">parent</span></code> 包和三个子包:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">parent</span><span class="o">/</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">one</span><span class="o">/</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">two</span><span class="o">/</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">three</span><span class="o">/</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
<p>导入 <code class="docutils literal notranslate"><span class="pre">parent.one</span></code> 将隐式地执行 <code class="docutils literal notranslate"><span class="pre">parent/__init__.py</span></code><code class="docutils literal notranslate"><span class="pre">parent/one/__init__.py</span></code>。 后续导入 <code class="docutils literal notranslate"><span class="pre">parent.two</span></code><code class="docutils literal notranslate"><span class="pre">parent.three</span></code> 则将分别执行 <code class="docutils literal notranslate"><span class="pre">parent/two/__init__.py</span></code><code class="docutils literal notranslate"><span class="pre">parent/three/__init__.py</span></code></p>
</section>
<section id="namespace-packages">
<h3><span class="section-number">5.2.2. </span>命名空间包<a class="headerlink" href="#namespace-packages" title="永久链接至标题"></a></h3>
<p id="index-5">命名空间包是由多个 <a class="reference internal" href="../glossary.html#term-portion"><span class="xref std std-term">部分</span></a> 构成的,每个部分为父包增加一个子包。 各个部分可能处于文件系统的不同位置。 部分也可能处于 zip 文件中、网络上,或者 Python 在导入期间可以搜索的其他地方。 命名空间包并不一定会直接对应到文件系统中的对象;它们有可能是无实体表示的虚拟模块。</p>
<p>命名空间包的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性不使用普通的列表。 而是使用定制的可迭代类型,如果其父包的路径 (或者最高层级包的 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a>) 发生改变,这种对象会在该包内的下一次导入尝试时自动执行新的对包部分的搜索。</p>
<p>命名空间包没有 <code class="docutils literal notranslate"><span class="pre">parent/__init__.py</span></code> 文件。 实际上,在导入搜索期间可能找到多个 <code class="docutils literal notranslate"><span class="pre">parent</span></code> 目录,每个都由不同的部分所提供。 因此 <code class="docutils literal notranslate"><span class="pre">parent/one</span></code> 的物理位置不一定与 <code class="docutils literal notranslate"><span class="pre">parent/two</span></code> 相邻。 在这种情况下Python 将为顶级的 <code class="docutils literal notranslate"><span class="pre">parent</span></code> 包创建一个命名空间包,无论是它本身还是它的某个子包被导入。</p>
<p>另请参阅 <span class="target" id="index-48"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0420"><strong>PEP 420</strong></a> 了解对命名空间包的规格描述。</p>
</section>
</section>
<section id="searching">
<h2><span class="section-number">5.3. </span>搜索<a class="headerlink" href="#searching" title="永久链接至标题"></a></h2>
<p>为了开始搜索Python 需要被导入模块(或者包,对于当前讨论来说两者没有差别)的完整 <a class="reference internal" href="../glossary.html#term-qualified-name"><span class="xref std std-term">限定名称</span></a>。 此名称可以来自 <a class="reference internal" href="simple_stmts.html#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句所带的各种参数,或者来自传给 <a class="reference internal" href="../library/importlib.html#importlib.import_module" title="importlib.import_module"><code class="xref py py-func docutils literal notranslate"><span class="pre">importlib.import_module()</span></code></a><a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 函数的形参。</p>
<p>此名称会在导入搜索的各个阶段被使用,它也可以是指向一个子模块的带点号路径,例如 <code class="docutils literal notranslate"><span class="pre">foo.bar.baz</span></code>。 在这种情况下Python 会先尝试导入 <code class="docutils literal notranslate"><span class="pre">foo</span></code>,然后是 <code class="docutils literal notranslate"><span class="pre">foo.bar</span></code>,最后是 <code class="docutils literal notranslate"><span class="pre">foo.bar.baz</span></code>。 如果这些导入中的任何一个失败,都会引发 <a class="reference internal" href="../library/exceptions.html#ModuleNotFoundError" title="ModuleNotFoundError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ModuleNotFoundError</span></code></a></p>
<section id="the-module-cache">
<h3><span class="section-number">5.3.1. </span>模块缓存<a class="headerlink" href="#the-module-cache" title="永久链接至标题"></a></h3>
<p id="index-7">在导入搜索期间首先会被检查的地方是 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a>。 这个映射起到缓存之前导入的所有模块的作用(包括其中间路径)。 因此如果之前导入过 <code class="docutils literal notranslate"><span class="pre">foo.bar.baz</span></code>,则 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 将包含 <code class="docutils literal notranslate"><span class="pre">foo</span></code>, <code class="docutils literal notranslate"><span class="pre">foo.bar</span></code><code class="docutils literal notranslate"><span class="pre">foo.bar.baz</span></code> 条目。 每个键的值就是相应的模块对象。</p>
<p>在导入期间,会在 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 查找模块名称,如存在则其关联的值就是需要导入的模块,导入过程完成。 然而,如果值为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,则会引发 <a class="reference internal" href="../library/exceptions.html#ModuleNotFoundError" title="ModuleNotFoundError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ModuleNotFoundError</span></code></a>。 如果找不到指定模块名称Python 将继续搜索该模块。</p>
<p><a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 是可写的。删除键可能不会破坏关联的模块(因为其他模块可能会保留对它的引用),但它会使命名模块的缓存条目无效,导致 Python 在下次导入时重新搜索命名模块。键也可以赋值为 <code class="docutils literal notranslate"><span class="pre">None</span></code> ,强制下一次导入模块导致 <a class="reference internal" href="../library/exceptions.html#ModuleNotFoundError" title="ModuleNotFoundError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ModuleNotFoundError</span></code></a></p>
<p>但是要小心,因为如果你还保有对某个模块对象的引用,同时停用其在 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中的缓存条目,然后又再次导入该名称的模块,则前后两个模块对象将 <em>不是</em> 同一个。 相反地,<a class="reference internal" href="../library/importlib.html#importlib.reload" title="importlib.reload"><code class="xref py py-func docutils literal notranslate"><span class="pre">importlib.reload()</span></code></a> 将重用 <em>同一个</em> 模块对象,并简单地通过重新运行模块的代码来重新初始化模块内容。</p>
</section>
<section id="finders-and-loaders">
<span id="id2"></span><h3><span class="section-number">5.3.2. </span>查找器和加载器<a class="headerlink" href="#finders-and-loaders" title="永久链接至标题"></a></h3>
<p id="index-8">如果指定名称的模块在 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 找不到,则将发起调用 Python 的导入协议以查找和加载该模块。 此协议由两个概念性模块构成,即 <a class="reference internal" href="../glossary.html#term-finder"><span class="xref std std-term">查找器</span></a><a class="reference internal" href="../glossary.html#term-loader"><span class="xref std std-term">加载器</span></a>。 查找器的任务是确定是否能使用其所知的策略找到该名称的模块。 同时实现这两种接口的对象称为 <a class="reference internal" href="../glossary.html#term-importer"><span class="xref std std-term">导入器</span></a> —— 它们在确定能加载所需的模块时会返回其自身。</p>
<p>Python 包含了多个默认查找器和导入器。 第一个知道如何定位内置模块,第二个知道如何定位冻结模块。 第三个默认查找器会在 <a class="reference internal" href="../glossary.html#term-import-path"><span class="xref std std-term">import path</span></a> 中搜索模块。 <a class="reference internal" href="../glossary.html#term-import-path"><span class="xref std std-term">import path</span></a> 是一个由文件系统路径或 zip 文件组成的位置列表。 它还可以扩展为搜索任意可定位资源,例如由 URL 指定的资源。</p>
<p>导入机制是可扩展的,因此可以加入新的查找器以扩展模块搜索的范围和作用域。</p>
<p>查找器并不真正加载模块。 如果它们能找到指定名称的模块,会返回一个 <em class="dfn">模块规格说明</em>,这是对模块导入相关信息的封装,供后续导入机制用于在加载模块时使用。</p>
<p>以下各节描述了有关查找器和加载器协议的更多细节,包括你应该如何创建并注册新的此类对象来扩展导入机制。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span>在之前的 Python 版本中,查找器会直接返回 <a class="reference internal" href="../glossary.html#term-loader"><span class="xref std std-term">加载器</span></a>,现在它们则返回模块规格说明,其中 <em>包含</em> 加载器。 加载器仍然在导入期间被使用,但负担的任务有所减少。</p>
</div>
</section>
<section id="import-hooks">
<h3><span class="section-number">5.3.3. </span>导入钩子<a class="headerlink" href="#import-hooks" title="永久链接至标题"></a></h3>
<p id="index-9">导入机制被设计为可扩展;其中的基本机制是 <em>导入钩子</em>。 导入钩子有两种类型: <em>元钩子</em><em>导入路径钩子</em></p>
<p>元钩子在导入过程开始时被调用,此时任何其他导入过程尚未发生,但 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 缓存查找除外。 这允许元钩子重载 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 过程、冻结模块甚至内置模块。 元钩子的注册是通过向 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a> 添加新的查找器对象,具体如下所述。</p>
<p>导入路径钩子是作为 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> (或 <code class="docutils literal notranslate"><span class="pre">package.__path__</span></code>) 过程的一部分,在遇到它们所关联的路径项的时候被调用。 导入路径钩子的注册是通过向 <a class="reference internal" href="../library/sys.html#sys.path_hooks" title="sys.path_hooks"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_hooks</span></code></a> 添加新的可调用对象,具体如下所述。</p>
</section>
<section id="the-meta-path">
<h3><span class="section-number">5.3.4. </span>元路径<a class="headerlink" href="#the-meta-path" title="永久链接至标题"></a></h3>
<p id="index-10">当指定名称的模块在 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中找不到时Python 会接着搜索 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a>,其中包含元路径查找器对象列表。 这些查找器按顺序被查询以确定它们是否知道如何处理该名称的模块。 元路径查找器必须实现名为 <a class="reference internal" href="../library/importlib.html#importlib.abc.MetaPathFinder.find_spec" title="importlib.abc.MetaPathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 的方法,该方法接受三个参数:名称、导入路径和目标模块(可选)。 元路径查找器可使用任何策略来确定它是否能处理指定名称的模块。</p>
<p>如果元路径查找器知道如何处理指定名称的模块,它将返回一个说明对象。 如果它不能处理该名称的模块,则会返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>。 如果 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a> 处理过程到达列表末尾仍未返回说明对象,则将引发 <a class="reference internal" href="../library/exceptions.html#ModuleNotFoundError" title="ModuleNotFoundError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ModuleNotFoundError</span></code></a>。 任何其他被引发异常将直接向上传播,并放弃导入过程。</p>
<p>元路径查找器的 <a class="reference internal" href="../library/importlib.html#importlib.abc.MetaPathFinder.find_spec" title="importlib.abc.MetaPathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 方法调用带有两到三个参数。 第一个是被导入模块的完整限定名称,例如 <code class="docutils literal notranslate"><span class="pre">foo.bar.baz</span></code>。 第二个参数是供模块搜索使用的路径条目。 对于最高层级模块,第二个参数为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,但对于子模块或子包,第二个参数为父包 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性的值。 如果相应的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性无法访问,将引发 <a class="reference internal" href="../library/exceptions.html#ModuleNotFoundError" title="ModuleNotFoundError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ModuleNotFoundError</span></code></a>。 第三个参数是一个将被作为稍后加载目标的现有模块对象。 导入系统仅会在重加载期间传入一个目标模块。</p>
<p>对于单个导入请求可以多次遍历元路径。 例如,假设所涉及的模块都尚未被缓存,则导入 <code class="docutils literal notranslate"><span class="pre">foo.bar.baz</span></code> 将首先执行顶级的导入,在每个元路径查找器 (<code class="docutils literal notranslate"><span class="pre">mpf</span></code>) 上调用 <code class="docutils literal notranslate"><span class="pre">mpf.find_spec(&quot;foo&quot;,</span> <span class="pre">None,</span> <span class="pre">None)</span></code>。 在导入 <code class="docutils literal notranslate"><span class="pre">foo</span></code> 之后,<code class="docutils literal notranslate"><span class="pre">foo.bar</span></code> 将通过第二次遍历元路径来导入,调用 <code class="docutils literal notranslate"><span class="pre">mpf.find_spec(&quot;foo.bar&quot;,</span> <span class="pre">foo.__path__,</span> <span class="pre">None)</span></code>。 一旦 <code class="docutils literal notranslate"><span class="pre">foo.bar</span></code> 完成导入,最后一次遍历将调用 <code class="docutils literal notranslate"><span class="pre">mpf.find_spec(&quot;foo.bar.baz&quot;,</span> <span class="pre">foo.bar.__path__,</span> <span class="pre">None)</span></code></p>
<p>有些元路径查找器只支持顶级导入。 当把 <code class="docutils literal notranslate"><span class="pre">None</span></code> 以外的对象作为第三个参数传入时,这些导入器将总是返回 <code class="docutils literal notranslate"><span class="pre">None</span></code></p>
<p>Python 的默认 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a> 具有三种元路径查找器,一种知道如何导入内置模块,一种知道如何导入冻结模块,还有一种知道如何导入来自 <a class="reference internal" href="../glossary.html#term-import-path"><span class="xref std std-term">import path</span></a> 的模块 (即 <a class="reference internal" href="../glossary.html#term-path-based-finder"><span class="xref std std-term">path based finder</span></a>)。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span>元路径查找器的 <a class="reference internal" href="../library/importlib.html#importlib.abc.MetaPathFinder.find_spec" title="importlib.abc.MetaPathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 方法替代了 <a class="reference internal" href="../library/importlib.html#importlib.abc.MetaPathFinder.find_module" title="importlib.abc.MetaPathFinder.find_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_module()</span></code></a>,后者现已弃用,它将继续可用但不会再做改变,导入机制仅会在查找器未实现 <code class="docutils literal notranslate"><span class="pre">find_spec()</span></code> 时尝试使用它。</p>
</div>
</section>
</section>
<section id="loading">
<h2><span class="section-number">5.4. </span>加载<a class="headerlink" href="#loading" title="永久链接至标题"></a></h2>
<p>当一个模块说明被找到时,导入机制将在加载该模块时使用它(及其所包含的加载器)。 下面是导入的加载部分所发生过程的简要说明:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">module</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">if</span> <span class="n">spec</span><span class="o">.</span><span class="n">loader</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span> <span class="ow">and</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">spec</span><span class="o">.</span><span class="n">loader</span><span class="p">,</span> <span class="s1">&#39;create_module&#39;</span><span class="p">):</span>
<span class="c1"># It is assumed &#39;exec_module&#39; will also be defined on the loader.</span>
<span class="n">module</span> <span class="o">=</span> <span class="n">spec</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">create_module</span><span class="p">(</span><span class="n">spec</span><span class="p">)</span>
<span class="k">if</span> <span class="n">module</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="n">module</span> <span class="o">=</span> <span class="n">ModuleType</span><span class="p">(</span><span class="n">spec</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="c1"># The import-related module attributes get set here:</span>
<span class="n">_init_module_attrs</span><span class="p">(</span><span class="n">spec</span><span class="p">,</span> <span class="n">module</span><span class="p">)</span>
<span class="k">if</span> <span class="n">spec</span><span class="o">.</span><span class="n">loader</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1"># unsupported</span>
<span class="k">raise</span> <span class="ne">ImportError</span>
<span class="k">if</span> <span class="n">spec</span><span class="o">.</span><span class="n">origin</span> <span class="ow">is</span> <span class="kc">None</span> <span class="ow">and</span> <span class="n">spec</span><span class="o">.</span><span class="n">submodule_search_locations</span> <span class="ow">is</span> <span class="ow">not</span> <span class="kc">None</span><span class="p">:</span>
<span class="c1"># namespace package</span>
<span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">spec</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">module</span>
<span class="k">elif</span> <span class="ow">not</span> <span class="nb">hasattr</span><span class="p">(</span><span class="n">spec</span><span class="o">.</span><span class="n">loader</span><span class="p">,</span> <span class="s1">&#39;exec_module&#39;</span><span class="p">):</span>
<span class="n">module</span> <span class="o">=</span> <span class="n">spec</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">load_module</span><span class="p">(</span><span class="n">spec</span><span class="o">.</span><span class="n">name</span><span class="p">)</span>
<span class="c1"># Set __loader__ and __package__ if missing.</span>
<span class="k">else</span><span class="p">:</span>
<span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">spec</span><span class="o">.</span><span class="n">name</span><span class="p">]</span> <span class="o">=</span> <span class="n">module</span>
<span class="k">try</span><span class="p">:</span>
<span class="n">spec</span><span class="o">.</span><span class="n">loader</span><span class="o">.</span><span class="n">exec_module</span><span class="p">(</span><span class="n">module</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">BaseException</span><span class="p">:</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">del</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">spec</span><span class="o">.</span><span class="n">name</span><span class="p">]</span>
<span class="k">except</span> <span class="ne">KeyError</span><span class="p">:</span>
<span class="k">pass</span>
<span class="k">raise</span>
<span class="k">return</span> <span class="n">sys</span><span class="o">.</span><span class="n">modules</span><span class="p">[</span><span class="n">spec</span><span class="o">.</span><span class="n">name</span><span class="p">]</span>
</pre></div>
</div>
<p>请注意以下细节:</p>
<blockquote>
<div><ul class="simple">
<li><p>如果在 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中存在指定名称的模块对象,导入操作会已经将其返回。</p></li>
<li><p>在加载器执行模块代码之前,该模块将存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中。 这一点很关键,因为该模块代码可能(直接或间接地)导入其自身;预先将其添加到 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 可防止在最坏情况下的无限递归和最好情况下的多次加载。</p></li>
<li><p>如果加载失败,则该模块 -- 只限加载失败的模块 -- 将从 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中移除。 任何已存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 缓存的模块,以及任何作为附带影响被成功加载的模块仍会保留在缓存中。 这与重新加载不同,后者会把即使加载失败的模块也保留在 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中。</p></li>
<li><p>在模块创建完成但还未执行之前,导入机制会设置导入相关模块属性(在上面的示例伪代码中为 “_init_module_attrs”详情参见 <a class="reference internal" href="#import-mod-attrs"><span class="std std-ref">后续部分</span></a></p></li>
<li><p>模块执行是加载的关键时刻,在此期间将填充模块的命名空间。 执行会完全委托给加载器,由加载器决定要填充的内容和方式。</p></li>
<li><p>在加载过程中创建并传递给 exec_module() 的模块并不一定就是在导入结束时返回的模块 <a class="footnote-reference brackets" href="#fnlo" id="id3">2</a></p></li>
</ul>
</div></blockquote>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span>导入系统已经接管了加载器建立样板的责任。 这些在以前是由 <a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.load_module" title="importlib.abc.Loader.load_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">importlib.abc.Loader.load_module()</span></code></a> 方法来执行的。</p>
</div>
<section id="loaders">
<h3><span class="section-number">5.4.1. </span>加载器<a class="headerlink" href="#loaders" title="永久链接至标题"></a></h3>
<p>模块加载器提供关键的加载功能:模块执行。 导入机制调用 <a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.exec_module" title="importlib.abc.Loader.exec_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">importlib.abc.Loader.exec_module()</span></code></a> 方法并传入一个参数来执行模块对象。 从 <a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.exec_module" title="importlib.abc.Loader.exec_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exec_module()</span></code></a> 返回的任何值都将被忽略。</p>
<p>加载器必须满足下列要求:</p>
<blockquote>
<div><ul class="simple">
<li><p>如果模块是一个 Python 模块(而非内置模块或动态加载的扩展),加载器应该在模块的全局命名空间 (<code class="docutils literal notranslate"><span class="pre">module.__dict__</span></code>) 中执行模块的代码。</p></li>
<li><p>如果加载器无法执行指定模块,它应该引发 <a class="reference internal" href="../library/exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ImportError</span></code></a>,不过在 <a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.exec_module" title="importlib.abc.Loader.exec_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exec_module()</span></code></a> 期间引发的任何其他异常也会被传播。</p></li>
</ul>
</div></blockquote>
<p>在许多情况下,查找器和加载器可以是同一对象;在此情况下 <a class="reference internal" href="../library/importlib.html#importlib.abc.MetaPathFinder.find_spec" title="importlib.abc.MetaPathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 方法将返回一个规格说明,其中加载器会被设为 <code class="docutils literal notranslate"><span class="pre">self</span></code></p>
<p>模块加载器可以选择通过实现 <a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.create_module" title="importlib.abc.Loader.create_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">create_module()</span></code></a> 方法在加载期间创建模块对象。 它接受一个参数,即模块规格说明,并返回新的模块对象供加载期间使用。 <code class="docutils literal notranslate"><span class="pre">create_module()</span></code> 不需要在模块对象上设置任何属性。 如果模块返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>,导入机制将自行创建新模块。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.4 新版功能: </span>加载器的 <a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.create_module" title="importlib.abc.Loader.create_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">create_module()</span></code></a> 方法。</p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span><a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.load_module" title="importlib.abc.Loader.load_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">load_module()</span></code></a> 方法被 <a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.exec_module" title="importlib.abc.Loader.exec_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">exec_module()</span></code></a> 所替代,导入机制会对加载的所有样板责任作出假定。</p>
<p>为了与现有的加载器兼容,导入机制会使用导入器的 <code class="docutils literal notranslate"><span class="pre">load_module()</span></code> 方法,如果它存在且导入器也未实现 <code class="docutils literal notranslate"><span class="pre">exec_module()</span></code>。 但是,<code class="docutils literal notranslate"><span class="pre">load_module()</span></code> 现已弃用,加载器应该转而实现 <code class="docutils literal notranslate"><span class="pre">exec_module()</span></code></p>
<p>除了执行模块之外,<code class="docutils literal notranslate"><span class="pre">load_module()</span></code> 方法必须实现上文描述的所有样板加载功能。 所有相同的限制仍然适用,并带有一些附加规定:</p>
<blockquote>
<div><ul class="simple">
<li><p>如果 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中存在指定名称的模块对象,加载器必须使用已存在的模块。 (否则 <a class="reference internal" href="../library/importlib.html#importlib.reload" title="importlib.reload"><code class="xref py py-func docutils literal notranslate"><span class="pre">importlib.reload()</span></code></a> 将无法正确工作。) 如果该名称模块不存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中,加载器必须创建一个新的模块对象并将其加入 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a></p></li>
<li><p>在加载器执行模块代码之前,模块 <em>必须</em> 存在于 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 之中,以防止无限递归或多次加载。</p></li>
<li><p>如果加载失败,加载器必须移除任何它已加入到 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中的模块,但它必须 <strong>仅限</strong> 移除加载失败的模块,且所移除的模块应为加载器自身显式加载的。</p></li>
</ul>
</div></blockquote>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.5 版更改: </span><code class="docutils literal notranslate"><span class="pre">exec_module()</span></code> 已定义但 <code class="docutils literal notranslate"><span class="pre">create_module()</span></code> 未定义时将引发 <a class="reference internal" href="../library/exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal notranslate"><span class="pre">DeprecationWarning</span></code></a></p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.6 版更改: </span><code class="docutils literal notranslate"><span class="pre">exec_module()</span></code> 已定义但 <code class="docutils literal notranslate"><span class="pre">create_module()</span></code> 未定义时将引发 <a class="reference internal" href="../library/exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ImportError</span></code></a></p>
</div>
</section>
<section id="submodules">
<h3><span class="section-number">5.4.2. </span>子模块<a class="headerlink" href="#submodules" title="永久链接至标题"></a></h3>
<p>当使用任意机制 (例如 <code class="docutils literal notranslate"><span class="pre">importlib</span></code> API, <code class="docutils literal notranslate"><span class="pre">import</span></code><code class="docutils literal notranslate"><span class="pre">import-from</span></code> 语句或者内置的 <code class="docutils literal notranslate"><span class="pre">__import__()</span></code>) 加载一个子模块时,父模块的命名空间中会添加一个对子模块对象的绑定。 例如,如果包 <code class="docutils literal notranslate"><span class="pre">spam</span></code> 有一个子模块 <code class="docutils literal notranslate"><span class="pre">foo</span></code>,则在导入 <code class="docutils literal notranslate"><span class="pre">spam.foo</span></code> 之后,<code class="docutils literal notranslate"><span class="pre">spam</span></code> 将具有一个 绑定到相应子模块的 <code class="docutils literal notranslate"><span class="pre">foo</span></code> 属性。 假如现在有如下的目录结构:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">spam</span><span class="o">/</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">foo</span><span class="o">.</span><span class="n">py</span>
<span class="n">bar</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
<p>并且 <code class="docutils literal notranslate"><span class="pre">spam/__init__.py</span></code> 中有如下几行内容:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">.foo</span> <span class="kn">import</span> <span class="n">Foo</span>
<span class="kn">from</span> <span class="nn">.bar</span> <span class="kn">import</span> <span class="n">Bar</span>
</pre></div>
</div>
<p>则执行如下代码将在 <code class="docutils literal notranslate"><span class="pre">spam</span></code> 模块中添加对 <code class="docutils literal notranslate"><span class="pre">foo</span></code><code class="docutils literal notranslate"><span class="pre">bar</span></code> 的名称绑定:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="kn">import</span> <span class="nn">spam</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">spam</span><span class="o">.</span><span class="n">foo</span>
<span class="go">&lt;module &#39;spam.foo&#39; from &#39;/tmp/imports/spam/foo.py&#39;&gt;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">spam</span><span class="o">.</span><span class="n">bar</span>
<span class="go">&lt;module &#39;spam.bar&#39; from &#39;/tmp/imports/spam/bar.py&#39;&gt;</span>
</pre></div>
</div>
<p>按照通常的 Python 名称绑定规则,这看起来可能会令人惊讶,但它实际上是导入系统的一个基本特性。 保持不变的一点是如果你有 <code class="docutils literal notranslate"><span class="pre">sys.modules['spam']</span></code><code class="docutils literal notranslate"><span class="pre">sys.modules['spam.foo']</span></code> (例如在上述导入之后就是如此),则后者必须显示为前者的 <code class="docutils literal notranslate"><span class="pre">foo</span></code> 属性。</p>
</section>
<section id="module-spec">
<h3><span class="section-number">5.4.3. </span>模块规格说明<a class="headerlink" href="#module-spec" title="永久链接至标题"></a></h3>
<p>导入机制在导入期间会使用有关每个模块的多种信息,特别是加载之前。 大多数信息都是所有模块通用的。 模块规格说明的目的是基于每个模块来封装这些导入相关信息。</p>
<p>在导入期间使用规格说明可允许状态在导入系统各组件之间传递,例如在创建模块规格说明的查找器和执行模块的加载器之间。 最重要的一点是,它允许导入机制执行加载的样板操作,在没有模块规格说明的情况下这是加载器的责任。</p>
<p>模块的规格说明会作为模块对象的 <code class="docutils literal notranslate"><span class="pre">__spec__</span></code> 属性对外公开。 有关模块规格的详细内容请参阅 <a class="reference internal" href="../library/importlib.html#importlib.machinery.ModuleSpec" title="importlib.machinery.ModuleSpec"><code class="xref py py-class docutils literal notranslate"><span class="pre">ModuleSpec</span></code></a></p>
<div class="versionadded">
<p><span class="versionmodified added">3.4 新版功能.</span></p>
</div>
</section>
<section id="import-related-module-attributes">
<span id="import-mod-attrs"></span><h3><span class="section-number">5.4.4. </span>导入相关的模块属性<a class="headerlink" href="#import-related-module-attributes" title="永久链接至标题"></a></h3>
<p>导入机制会在加载期间会根据模块的规格说明填充每个模块对象的这些属性,并在加载器执行模块之前完成。</p>
<dl class="attribute">
<dt id="__name__">
<code class="sig-name descname">__name__</code><a class="headerlink" href="#__name__" title="永久链接至目标"></a></dt>
<dd><p><code class="docutils literal notranslate"><span class="pre">__name__</span></code> 属性必须被设为模块的完整限定名称。 此名称被用来在导入系统中唯一地标识模块。</p>
</dd></dl>
<dl class="attribute">
<dt id="__loader__">
<code class="sig-name descname">__loader__</code><a class="headerlink" href="#__loader__" title="永久链接至目标"></a></dt>
<dd><p><code class="docutils literal notranslate"><span class="pre">__loader__</span></code> 属性必须被设为导入系统在加载模块时使用的加载器对象。 这主要是用于内省,但也可用于额外的加载器专用功能,例如获取关联到加载器的数据。</p>
</dd></dl>
<dl class="attribute">
<dt id="__package__">
<code class="sig-name descname">__package__</code><a class="headerlink" href="#__package__" title="永久链接至目标"></a></dt>
<dd><p>模块的 <code class="docutils literal notranslate"><span class="pre">__package__</span></code> 属性必须设定。 其取值必须为一个字符串,但可以与 <code class="docutils literal notranslate"><span class="pre">__name__</span></code> 取相同的值。 当模块是包时,其 <code class="docutils literal notranslate"><span class="pre">__package__</span></code> 值应该设为其 <code class="docutils literal notranslate"><span class="pre">__name__</span></code> 值。 当模块不是包时,对于最高层级模块 <code class="docutils literal notranslate"><span class="pre">__package__</span></code> 应该设为空字符串,对于子模块则应该设为其父包名。 更多详情可参阅 <span class="target" id="index-49"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0366"><strong>PEP 366</strong></a></p>
<p>该属性取代 <code class="docutils literal notranslate"><span class="pre">__name__</span></code> 被用来为主模块计算显式相对导入,相关定义见 <span class="target" id="index-50"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0366"><strong>PEP 366</strong></a>。 预期它与 <code class="docutils literal notranslate"><span class="pre">__spec__.parent</span></code> 具有相同的值。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.6 版更改: </span><code class="docutils literal notranslate"><span class="pre">__package__</span></code> 预期与 <code class="docutils literal notranslate"><span class="pre">__spec__.parent</span></code> 具有相同的值。</p>
</div>
</dd></dl>
<dl class="attribute">
<dt id="__spec__">
<code class="sig-name descname">__spec__</code><a class="headerlink" href="#__spec__" title="永久链接至目标"></a></dt>
<dd><p><code class="docutils literal notranslate"><span class="pre">__spec__</span></code> 属性必须设为在导入模块时要使用的模块规格说明。 对 <code class="docutils literal notranslate"><span class="pre">__spec__</span></code> 的正确设定将同时作用于 <a class="reference internal" href="toplevel_components.html#programs"><span class="std std-ref">解释器启动期间初始化的模块</span></a>。 唯一的例外是 <code class="docutils literal notranslate"><span class="pre">__main__</span></code>,其中的 <code class="docutils literal notranslate"><span class="pre">__spec__</span></code><a class="reference internal" href="#main-spec"><span class="std std-ref">在某些情况下设为 None</span></a>.</p>
<p><code class="docutils literal notranslate"><span class="pre">__package__</span></code> 未定义时, <code class="docutils literal notranslate"><span class="pre">__spec__.parent</span></code> 会被用作回退项。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.4 新版功能.</span></p>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.6 版更改: </span><code class="docutils literal notranslate"><span class="pre">__package__</span></code> 未定义时,<code class="docutils literal notranslate"><span class="pre">__spec__.parent</span></code> 会被用作回退项。</p>
</div>
</dd></dl>
<dl class="attribute">
<dt id="__path__">
<code class="sig-name descname">__path__</code><a class="headerlink" href="#__path__" title="永久链接至目标"></a></dt>
<dd><p>如果模块为包(不论是正规包还是命名空间包),则必须设置模块对象的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性。 属性值必须为可迭代对象,但如果 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 没有进一步的用处则可以为空。 如果 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 不为空,则在迭代时它应该产生字符串。 有关 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 语义的更多细节将在 <a class="reference internal" href="#package-path-rules"><span class="std std-ref">下文</span></a> 中给出。</p>
<p>不是包的模块不应该具有 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性。</p>
</dd></dl>
<dl class="attribute">
<dt id="__file__">
<code class="sig-name descname">__file__</code><a class="headerlink" href="#__file__" title="永久链接至目标"></a></dt>
<dd></dd></dl>
<dl class="attribute">
<dt id="__cached__">
<code class="sig-name descname">__cached__</code><a class="headerlink" href="#__cached__" title="永久链接至目标"></a></dt>
<dd><p><code class="docutils literal notranslate"><span class="pre">__file__</span></code> 是可选项。 如果设置,此属性的值必须为字符串。 导入系统可以选择在其没有语法意义时不设置 <code class="docutils literal notranslate"><span class="pre">__file__</span></code> (例如从数据库加载的模块)。</p>
<p>如果设置了 <code class="docutils literal notranslate"><span class="pre">__file__</span></code>,则也可以再设置 <code class="docutils literal notranslate"><span class="pre">__cached__</span></code> 属性,后者取值为编译版本代码(例如字节码文件)所在的路径。 设置此属性不要求文件已存在;该路径可以简单地指向应该存放编译文件的位置 (参见 <span class="target" id="index-51"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3147"><strong>PEP 3147</strong></a>)。</p>
<p>当未设置 <code class="docutils literal notranslate"><span class="pre">__file__</span></code> 时也可以设置 <code class="docutils literal notranslate"><span class="pre">__cached__</span></code>。 但是,那样的场景很不典型。 最终,加载器会使用 <code class="docutils literal notranslate"><span class="pre">__file__</span></code> 和/或 <code class="docutils literal notranslate"><span class="pre">__cached__</span></code>。 因此如果一个加载器可以从缓存加载模块但是不能从文件加载,那种非典型场景就是适当的。</p>
</dd></dl>
</section>
<section id="module-path">
<span id="package-path-rules"></span><h3><span class="section-number">5.4.5. </span>module.__path__<a class="headerlink" href="#module-path" title="永久链接至标题"></a></h3>
<p>根据定义,如果一个模块具有 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性,它就是包。</p>
<p>包的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性会在导入其子包期间被使用。 在导入机制内部,它的功能与 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 基本相同,即在导入期间提供一个模块搜索位置列表。 但是,<code class="docutils literal notranslate"><span class="pre">__path__</span></code> 通常会比 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 受到更多限制。</p>
<p><code class="docutils literal notranslate"><span class="pre">__path__</span></code> 必须是由字符串组成的可迭代对象,但它也可以为空。 作用于 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 的规则同样适用于包的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code>,并且 <a class="reference internal" href="../library/sys.html#sys.path_hooks" title="sys.path_hooks"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_hooks</span></code></a> (见下文) 会在遍历包的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 时被查询。</p>
<p>包的 <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> 文件可以设置或更改包的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性,而且这是在 <span class="target" id="index-52"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0420"><strong>PEP 420</strong></a> 之前实现命名空间包的典型方式。 随着 <span class="target" id="index-53"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0420"><strong>PEP 420</strong></a> 的引入,命名空间包不再需要提供仅包含 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 操控代码的 <code class="docutils literal notranslate"><span class="pre">__init__.py</span></code> 文件;导入机制会自动为命名空间包正确地设置 <code class="docutils literal notranslate"><span class="pre">__path__</span></code></p>
</section>
<section id="module-reprs">
<h3><span class="section-number">5.4.6. </span>模块的 repr<a class="headerlink" href="#module-reprs" title="永久链接至标题"></a></h3>
<p>默认情况下,全部模块都具有一个可用的 repr但是你可以依据上述的属性设置在模块的规格说明中更为显式地控制模块对象的 repr。</p>
<p>如果模块具有 spec (<code class="docutils literal notranslate"><span class="pre">__spec__</span></code>),导入机制将尝试用它来生成一个 repr。 如果生成失败或找不到 spec导入系统将使用模块中的各种可用信息来制作一个默认 repr。 它将尝试使用 <code class="docutils literal notranslate"><span class="pre">module.__name__</span></code>, <code class="docutils literal notranslate"><span class="pre">module.__file__</span></code> 以及 <code class="docutils literal notranslate"><span class="pre">module.__loader__</span></code> 作为 repr 的输入,并将任何丢失的信息赋为默认值。</p>
<p>以下是所使用的确切规则:</p>
<blockquote>
<div><ul class="simple">
<li><p>如果模块具有 <code class="docutils literal notranslate"><span class="pre">__spec__</span></code> 属性,其中的规格信息会被用来生成 repr。 被查询的属性有 &quot;name&quot;, &quot;loader&quot;, &quot;origin&quot;&quot;has_location&quot; 等等。</p></li>
<li><p>如果模块具有 <code class="docutils literal notranslate"><span class="pre">__file__</span></code> 属性,这会被用作模块 repr 的一部分。</p></li>
<li><p>如果模块没有 <code class="docutils literal notranslate"><span class="pre">__file__</span></code> 但是有 <code class="docutils literal notranslate"><span class="pre">__loader__</span></code> 且取值不为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,则加载器的 repr 会被用作模块 repr 的一部分。</p></li>
<li><p>对于其他情况,仅在 repr 中使用模块的 <code class="docutils literal notranslate"><span class="pre">__name__</span></code></p></li>
</ul>
</div></blockquote>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span><a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.module_repr" title="importlib.abc.Loader.module_repr"><code class="xref py py-meth docutils literal notranslate"><span class="pre">loader.module_repr()</span></code></a> 已弃用,导入机制现在使用模块规格说明来生成模块 repr。</p>
<p>为了向后兼容 Python 3.3,如果加载器定义了 <a class="reference internal" href="../library/importlib.html#importlib.abc.Loader.module_repr" title="importlib.abc.Loader.module_repr"><code class="xref py py-meth docutils literal notranslate"><span class="pre">module_repr()</span></code></a> 方法,则会在尝试上述两种方式之前先调用该方法来生成模块 repr。 但请注意此方法已弃用。</p>
</div>
</section>
<section id="cached-bytecode-invalidation">
<span id="pyc-invalidation"></span><h3><span class="section-number">5.4.7. </span>已缓存字节码的失效<a class="headerlink" href="#cached-bytecode-invalidation" title="永久链接至标题"></a></h3>
<p>在 Python 从 <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件加载已缓存字节码之前,它会检查缓存是否由最新的 <code class="docutils literal notranslate"><span class="pre">.py</span></code> 源文件所生成。 默认情况下Python 通过在所写入缓存文件中保存源文件的最新修改时间戳和大小来实现这一点。 在运行时,导入系统会通过比对缓存文件中保存的元数据和源文件的元数据确定该缓存的有效性。</p>
<p>Python 也支持“基于哈希的”缓存文件,即保存源文件内容的哈希值而不是其元数据。 存在两种基于哈希的 <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件:检查型和非检查型。 对于检查型基于哈希的 <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件Python 会通过求哈希源文件并将结果哈希值与缓存文件中的哈希值比对来确定缓存有效性。 如果检查型基于哈希的缓存文件被确定为失效Python 会重新生成并写入一个新的检查型基于哈希的缓存文件。 对于非检查型 <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件,只要其存在 Python 就会直接认定缓存文件有效。 确定基于哈希的 <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件有效性的行为可通过 <a class="reference internal" href="../using/cmdline.html#cmdoption-check-hash-based-pycs"><code class="xref std std-option docutils literal notranslate"><span class="pre">--check-hash-based-pycs</span></code></a> 旗标来重载。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>增加了基于哈希的 <code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件。在此之前Python 只支持基于时间戳来确定字节码缓存的有效性。</p>
</div>
</section>
</section>
<section id="the-path-based-finder">
<h2><span class="section-number">5.5. </span>基于路径的查找器<a class="headerlink" href="#the-path-based-finder" title="永久链接至标题"></a></h2>
<p id="index-16">在之前已经提及Python 带有几种默认的元路径查找器。 其中之一是 <a class="reference internal" href="../glossary.html#term-path-based-finder"><span class="xref std std-term">path based finder</span></a> (<a class="reference internal" href="../library/importlib.html#importlib.machinery.PathFinder" title="importlib.machinery.PathFinder"><code class="xref py py-class docutils literal notranslate"><span class="pre">PathFinder</span></code></a>),它会搜索包含一个 <a class="reference internal" href="../glossary.html#term-path-entry"><span class="xref std std-term">路径条目</span></a> 列表的 <a class="reference internal" href="../glossary.html#term-import-path"><span class="xref std std-term">import path</span></a>。 每个路径条目指定一个用于搜索模块的位置。</p>
<p>基于路径的查找器自身并不知道如何进行导入。 它只是遍历单独的路径条目,将它们各自关联到某个知道如何处理特定类型路径的路径条目查找器。</p>
<p>默认的路径条目查找器集合实现了在文件系统中查找模块的所有语义,可处理多种特殊文件类型例如 Python 源码 (<code class="docutils literal notranslate"><span class="pre">.py</span></code> 文件)Python 字节码 (<code class="docutils literal notranslate"><span class="pre">.pyc</span></code> 文件) 以及共享库 (例如 <code class="docutils literal notranslate"><span class="pre">.so</span></code> 文件)。 在标准库中 <a class="reference internal" href="../library/zipimport.html#module-zipimport" title="zipimport: Support for importing Python modules from ZIP archives."><code class="xref py py-mod docutils literal notranslate"><span class="pre">zipimport</span></code></a> 模块的支持下,默认路径条目查找器还能处理所有来自 zip 文件的上述文件类型。</p>
<p>路径条目不必仅限于文件系统位置。 它们可以指向 URL、数据库查询或可以用字符串指定的任何其他位置。</p>
<p>基于路径的查找器还提供了额外的钩子和协议以便能扩展和定制可搜索路径条目的类型。 例如,如果你想要支持网络 URL 形式的路径条目,你可以编写一个实现 HTTP 语义在网络上查找模块的钩子。 这个钩子(可调用对象)应当返回一个支持下述协议的 <a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">path entry finder</span></a>,以被用来获取一个专门针对来自网络的模块的加载器。</p>
<p>预先的警告:本节和上节都使用了 <em>查找器</em> 这一术语,并通过 <a class="reference internal" href="../glossary.html#term-meta-path-finder"><span class="xref std std-term">meta path finder</span></a><a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">path entry finder</span></a> 两个术语来明确区分它们。 这两种类型的查找器非常相似,支持相似的协议,且在导入过程中以相似的方式运作,但关键的一点是要记住它们是有微妙差异的。 特别地,元路径查找器作用于导入过程的开始,主要是启动 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a> 遍历。</p>
<p>相比之下,路径条目查找器在某种意义上说是基于路径的查找器的实现细节,实际上,如果需要从 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a> 移除基于路径的查找器,并不会有任何路径条目查找器被发起调用。</p>
<section id="path-entry-finders">
<h3><span class="section-number">5.5.1. </span>路径条目查找器<a class="headerlink" href="#path-entry-finders" title="永久链接至标题"></a></h3>
<p id="index-17"><a class="reference internal" href="../glossary.html#term-path-based-finder"><span class="xref std std-term">path based finder</span></a> 会负责查找和加载通过 <a class="reference internal" href="../glossary.html#term-path-entry"><span class="xref std std-term">path entry</span></a> 字符串来指定位置的 Python 模块和包。 多数路径条目所指定的是文件系统中的位置,但它们并不必受限于此。</p>
<p>作为一种元路径查找器,<a class="reference internal" href="../glossary.html#term-path-based-finder"><span class="xref std std-term">path based finder</span></a> 实现了上文描述的 <a class="reference internal" href="../library/importlib.html#importlib.abc.MetaPathFinder.find_spec" title="importlib.abc.MetaPathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 协议,但是它还对外公开了一些附加钩子,可被用来定制模块如何从 <a class="reference internal" href="../glossary.html#term-import-path"><span class="xref std std-term">import path</span></a> 查找和加载。</p>
<p>有三个变量由 <a class="reference internal" href="../glossary.html#term-path-based-finder"><span class="xref std std-term">path based finder</span></a>, <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a>, <a class="reference internal" href="../library/sys.html#sys.path_hooks" title="sys.path_hooks"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_hooks</span></code></a><a class="reference internal" href="../library/sys.html#sys.path_importer_cache" title="sys.path_importer_cache"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_importer_cache</span></code></a> 所使用。 包对象的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性也会被使用。 它们提供了可用于定制导入机制的额外方式。</p>
<p><a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 包含一个提供模块和包搜索位置的字符串列表。 它初始化自 <code class="xref py py-data docutils literal notranslate"><span class="pre">PYTHONPATH</span></code> 环境变量以及多种其他特定安装和实现的默认设置。 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 条目可指定的名称有文件系统中的目录、zip 文件和其他可用于搜索模块的潜在“位置”(参见 <a class="reference internal" href="../library/site.html#module-site" title="site: Module responsible for site-specific configuration."><code class="xref py py-mod docutils literal notranslate"><span class="pre">site</span></code></a> 模块),例如 URL 或数据库查询等。 在 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 中只能出现字符串和字节串;所有其他数据类型都会被忽略。 字节串条目使用的编码由单独的 <a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">路径条目查找器</span></a> 来确定。</p>
<p><a class="reference internal" href="../glossary.html#term-path-based-finder"><span class="xref std std-term">path based finder</span></a> 是一种 <a class="reference internal" href="../glossary.html#term-meta-path-finder"><span class="xref std std-term">meta path finder</span></a>,因此导入机制会通过调用上文描述的基于路径的查找器的 <a class="reference internal" href="../library/importlib.html#importlib.machinery.PathFinder.find_spec" title="importlib.machinery.PathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 方法来启动 <a class="reference internal" href="../glossary.html#term-import-path"><span class="xref std std-term">import path</span></a> 搜索。 当要向 <a class="reference internal" href="../library/importlib.html#importlib.machinery.PathFinder.find_spec" title="importlib.machinery.PathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 传入 <code class="docutils literal notranslate"><span class="pre">path</span></code> 参数时,它将是一个可遍历的字符串列表 —— 通常为用来在其内部进行导入的包的 <code class="docutils literal notranslate"><span class="pre">__path__</span></code> 属性。 如果 <code class="docutils literal notranslate"><span class="pre">path</span></code> 参数为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,这表示最高层级的导入,将会使用 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a></p>
<p>基于路径的查找器会迭代搜索路径中的每个条目,并且每次都查找与路径条目对应的 <a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">path entry finder</span></a> (<a class="reference internal" href="../library/importlib.html#importlib.abc.PathEntryFinder" title="importlib.abc.PathEntryFinder"><code class="xref py py-class docutils literal notranslate"><span class="pre">PathEntryFinder</span></code></a>)。 因为这种操作可能很耗费资源(例如搜索会有 <cite>stat()</cite> 调用的开销),基于路径的查找器会维持一个缓存来将路径条目映射到路径条目查找器。 这个缓存放于 <a class="reference internal" href="../library/sys.html#sys.path_importer_cache" title="sys.path_importer_cache"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_importer_cache</span></code></a> (尽管如此命名,但这个缓存实际存放的是查找器对象而非仅限于 <a class="reference internal" href="../glossary.html#term-importer"><span class="xref std std-term">importer</span></a> 对象)。 通过这种方式,对特定 <a class="reference internal" href="../glossary.html#term-path-entry"><span class="xref std std-term">path entry</span></a> 位置的 <a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">path entry finder</span></a> 的高耗费搜索只需进行一次。 用户代码可以自由地从 <a class="reference internal" href="../library/sys.html#sys.path_importer_cache" title="sys.path_importer_cache"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_importer_cache</span></code></a> 移除缓存条目,以强制基于路径的查找器再次执行路径条目搜索 <a class="footnote-reference brackets" href="#fnpic" id="id4">3</a></p>
<p>如果路径条目不存在于缓存中,基于路径的查找器会迭代 <a class="reference internal" href="../library/sys.html#sys.path_hooks" title="sys.path_hooks"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_hooks</span></code></a> 中的每个可调用对象。 对此列表中的每个 <a class="reference internal" href="../glossary.html#term-path-entry-hook"><span class="xref std std-term">路径条目钩子</span></a> 的调用会带有一个参数,即要搜索的路径条目。 每个可调用对象或是返回可处理路径条目的 <a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">path entry finder</span></a>,或是引发 <a class="reference internal" href="../library/exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ImportError</span></code></a>。 基于路径的查找器使用 <a class="reference internal" href="../library/exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ImportError</span></code></a> 来表示钩子无法找到与 <a class="reference internal" href="../glossary.html#term-path-entry"><span class="xref std std-term">path entry</span></a> 相对应的 <a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">path entry finder</span></a>。 该异常会被忽略并继续进行 <a class="reference internal" href="../glossary.html#term-import-path"><span class="xref std std-term">import path</span></a> 的迭代。 每个钩子应该期待接收一个字符串或字节串对象;字节串对象的编码由钩子决定(例如可以是文件系统使用的编码 UTF-8 或其它编码),如果钩子无法解码参数,它应该引发 <a class="reference internal" href="../library/exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ImportError</span></code></a></p>
<p>如果 <a class="reference internal" href="../library/sys.html#sys.path_hooks" title="sys.path_hooks"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_hooks</span></code></a> 迭代结束时没有返回 <a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">path entry finder</span></a>,则基于路径的查找器 <a class="reference internal" href="../library/importlib.html#importlib.machinery.PathFinder.find_spec" title="importlib.machinery.PathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 方法将在 <a class="reference internal" href="../library/sys.html#sys.path_importer_cache" title="sys.path_importer_cache"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_importer_cache</span></code></a> 中存入 <code class="docutils literal notranslate"><span class="pre">None</span></code> (表示此路径条目没有对应的查找器) 并返回 <code class="docutils literal notranslate"><span class="pre">None</span></code>,表示此 <a class="reference internal" href="../glossary.html#term-meta-path-finder"><span class="xref std std-term">meta path finder</span></a> 无法找到该模块。</p>
<p>如果 <a class="reference internal" href="../library/sys.html#sys.path_hooks" title="sys.path_hooks"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_hooks</span></code></a> 中的某个 <a class="reference internal" href="../glossary.html#term-path-entry-hook"><span class="xref std std-term">path entry hook</span></a> 可调用对象的返回值 <em></em> 一个 <a class="reference internal" href="../glossary.html#term-path-entry-finder"><span class="xref std std-term">path entry finder</span></a>,则以下协议会被用来向查找器请求一个模块的规格说明,并在加载该模块时被使用。</p>
<p>当前工作目录 -- 由一个空字符串表示 -- 的处理方式与 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 中的其他条目略有不同。 首先,如果发现当前工作目录不存在,则 <a class="reference internal" href="../library/sys.html#sys.path_importer_cache" title="sys.path_importer_cache"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_importer_cache</span></code></a> 中不会存放任何值。 其次,每个模块查找会对当前工作目录的值进行全新查找。 第三,由 <a class="reference internal" href="../library/sys.html#sys.path_importer_cache" title="sys.path_importer_cache"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_importer_cache</span></code></a> 所使用并由 <a class="reference internal" href="../library/importlib.html#importlib.machinery.PathFinder.find_spec" title="importlib.machinery.PathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">importlib.machinery.PathFinder.find_spec()</span></code></a> 所返回的路径将是实际的当前工作目录而非空字符串。</p>
</section>
<section id="path-entry-finder-protocol">
<h3><span class="section-number">5.5.2. </span>路径条目查找器协议<a class="headerlink" href="#path-entry-finder-protocol" title="永久链接至标题"></a></h3>
<p>为了支持模块和已初始化包的导入,也为了给命名空间包提供组成部分,路径条目查找器必须实现 <a class="reference internal" href="../library/importlib.html#importlib.abc.PathEntryFinder.find_spec" title="importlib.abc.PathEntryFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 方法。</p>
<p><a class="reference internal" href="../library/importlib.html#importlib.abc.PathEntryFinder.find_spec" title="importlib.abc.PathEntryFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 接受两个参数,即要导入模块的完整限定名称,以及(可选的)目标模块。 <code class="docutils literal notranslate"><span class="pre">find_spec()</span></code> 返回模块的完全填充好的规格说明。 这个规格说明总是包含“加载器”集合(但有一个例外)。</p>
<p>为了向导入机制提示该规格说明代表一个命名空间 <a class="reference internal" href="../glossary.html#term-portion"><span class="xref std std-term">portion</span></a>,路径条目查找器会将 &quot;submodule_search_locations&quot; 设为一个包含该部分的列表。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.4 版更改: </span><a class="reference internal" href="../library/importlib.html#importlib.abc.PathEntryFinder.find_spec" title="importlib.abc.PathEntryFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 替代了 <a class="reference internal" href="../library/importlib.html#importlib.abc.PathEntryFinder.find_loader" title="importlib.abc.PathEntryFinder.find_loader"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_loader()</span></code></a><a class="reference internal" href="../library/importlib.html#importlib.abc.PathEntryFinder.find_module" title="importlib.abc.PathEntryFinder.find_module"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_module()</span></code></a>,后两者现在都已弃用,但会在 <code class="docutils literal notranslate"><span class="pre">find_spec()</span></code> 未定义时被使用。</p>
<p>较旧的路径条目查找器可能会实现这两个已弃用的方法中的一个而没有实现 <code class="docutils literal notranslate"><span class="pre">find_spec()</span></code>。 为保持向后兼容,这两个方法仍会被接受。 但是,如果在路径条目查找器上实现了 <code class="docutils literal notranslate"><span class="pre">find_spec()</span></code>,这两个遗留方法就会被忽略。</p>
<p><a class="reference internal" href="../library/importlib.html#importlib.abc.PathEntryFinder.find_loader" title="importlib.abc.PathEntryFinder.find_loader"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_loader()</span></code></a> 接受一个参数,即要导入模块的完整限定名称。 <code class="docutils literal notranslate"><span class="pre">find_loader()</span></code> 返回一个 2 元组,其中第一项是加载器而第二项是命名空间 <a class="reference internal" href="../glossary.html#term-portion"><span class="xref std std-term">portion</span></a></p>
<p>为了向后兼容其他导入协议的实现,许多路径条目查找器也同样支持元路径查找器所支持的传统 <code class="docutils literal notranslate"><span class="pre">find_module()</span></code> 方法。 但是路径条目查找器 <code class="docutils literal notranslate"><span class="pre">find_module()</span></code> 方法的调用绝不会带有 <code class="docutils literal notranslate"><span class="pre">path</span></code> 参数(它们被期望记录来自对路径钩子初始调用的恰当路径信息)。</p>
<p>路径条目查找器的 <code class="docutils literal notranslate"><span class="pre">find_module()</span></code> 方法已弃用,因为它不允许路径条目查找器为命名空间包提供部分。 如果 <code class="docutils literal notranslate"><span class="pre">find_loader()</span></code><code class="docutils literal notranslate"><span class="pre">find_module()</span></code> 同时存在于一个路径条目查找器中,导入系统将总是调用 <code class="docutils literal notranslate"><span class="pre">find_loader()</span></code> 而不选择 <code class="docutils literal notranslate"><span class="pre">find_module()</span></code></p>
</div>
</section>
</section>
<section id="replacing-the-standard-import-system">
<h2><span class="section-number">5.6. </span>替换标准导入系统<a class="headerlink" href="#replacing-the-standard-import-system" title="永久链接至标题"></a></h2>
<p>替换整个导入系统的最可靠机制是移除 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a> 的默认内容,,将其完全替换为自定义的元路径钩子。</p>
<p>一个可行的方式是仅改变导入语句的行为而不影响访问导入系统的其他 API那么替换内置的 <a class="reference internal" href="../library/functions.html#__import__" title="__import__"><code class="xref py py-func docutils literal notranslate"><span class="pre">__import__()</span></code></a> 函数可能就够了。 这种技巧也可以在模块层级上运用,即只在某个模块内部改变导入语句的行为。</p>
<p>想要选择性地预先防止在元路径上从一个钩子导入某些模块(而不是完全禁用标准导入系统),只需直接从 <a class="reference internal" href="../library/importlib.html#importlib.abc.MetaPathFinder.find_spec" title="importlib.abc.MetaPathFinder.find_spec"><code class="xref py py-meth docutils literal notranslate"><span class="pre">find_spec()</span></code></a> 引发 <a class="reference internal" href="../library/exceptions.html#ModuleNotFoundError" title="ModuleNotFoundError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ModuleNotFoundError</span></code></a> 而非返回 <code class="docutils literal notranslate"><span class="pre">None</span></code> 就足够了。 返回后者表示元路径搜索应当继续,而引发异常则会立即终止搜索。</p>
</section>
<section id="package-relative-imports">
<span id="relativeimports"></span><h2><span class="section-number">5.7. </span>包相对导入<a class="headerlink" href="#package-relative-imports" title="永久链接至标题"></a></h2>
<p>相对导入使用前缀点号。 一个前缀点号表示相对导入从当前包开始。 两个或更多前缀点号表示对当前包的上级包的相对导入,第一个点号之后的每个点号代表一级。 例如,给定以下的包布局结构:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">package</span><span class="o">/</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">subpackage1</span><span class="o">/</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">moduleX</span><span class="o">.</span><span class="n">py</span>
<span class="n">moduleY</span><span class="o">.</span><span class="n">py</span>
<span class="n">subpackage2</span><span class="o">/</span>
<span class="fm">__init__</span><span class="o">.</span><span class="n">py</span>
<span class="n">moduleZ</span><span class="o">.</span><span class="n">py</span>
<span class="n">moduleA</span><span class="o">.</span><span class="n">py</span>
</pre></div>
</div>
<p>不论是在 <code class="docutils literal notranslate"><span class="pre">subpackage1/moduleX.py</span></code> 还是 <code class="docutils literal notranslate"><span class="pre">subpackage1/__init__.py</span></code> 中,以下导入都是有效的:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">.moduleY</span> <span class="kn">import</span> <span class="n">spam</span>
<span class="kn">from</span> <span class="nn">.moduleY</span> <span class="kn">import</span> <span class="n">spam</span> <span class="k">as</span> <span class="n">ham</span>
<span class="kn">from</span> <span class="nn">.</span> <span class="kn">import</span> <span class="n">moduleY</span>
<span class="kn">from</span> <span class="nn">..subpackage1</span> <span class="kn">import</span> <span class="n">moduleY</span>
<span class="kn">from</span> <span class="nn">..subpackage2.moduleZ</span> <span class="kn">import</span> <span class="n">eggs</span>
<span class="kn">from</span> <span class="nn">..moduleA</span> <span class="kn">import</span> <span class="n">foo</span>
</pre></div>
</div>
<p>绝对导入可以使用 <code class="docutils literal notranslate"><span class="pre">import</span> <span class="pre">&lt;&gt;</span></code><code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">&lt;&gt;</span> <span class="pre">import</span> <span class="pre">&lt;&gt;</span></code> 语法,但相对导入只能使用第二种形式;其中的原因在于:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">XXX.YYY.ZZZ</span>
</pre></div>
</div>
<p>应当提供 <code class="docutils literal notranslate"><span class="pre">XXX.YYY.ZZZ</span></code> 作为可用表达式,但 .moduleY 不是一个有效的表达式。</p>
</section>
<section id="special-considerations-for-main">
<h2><span class="section-number">5.8. </span>有关 __main__ 的特殊事项<a class="headerlink" href="#special-considerations-for-main" title="永久链接至标题"></a></h2>
<p>对于 Python 的导入系统来说 <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a> 模块是一个特殊情况。 正如在 <a class="reference internal" href="toplevel_components.html#programs"><span class="std std-ref">另一节</span></a> 中所述,<code class="docutils literal notranslate"><span class="pre">__main__</span></code> 模块是在解释器启动时直接初始化的,与 <a class="reference internal" href="../library/sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sys</span></code></a><a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a> 很类似。 但是,与那两者不同,它并不被严格归类为内置模块。 这是因为 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 被初始化的方式依赖于发起调用解释器所附带的旗标和其他选项。</p>
<section id="main-spec">
<span id="id5"></span><h3><span class="section-number">5.8.1. </span>__main__.__spec__<a class="headerlink" href="#main-spec" title="永久链接至标题"></a></h3>
<p>根据 <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a> 被初始化的方式,<code class="docutils literal notranslate"><span class="pre">__main__.__spec__</span></code> 会被设置相应值或是 <code class="docutils literal notranslate"><span class="pre">None</span></code></p>
<p>当 Python 附加 <a class="reference internal" href="../using/cmdline.html#cmdoption-m"><code class="xref std std-option docutils literal notranslate"><span class="pre">-m</span></code></a> 选项启动时,<code class="docutils literal notranslate"><span class="pre">__spec__</span></code> 会被设为相应模块或包的模块规格说明。 <code class="docutils literal notranslate"><span class="pre">__spec__</span></code> 也会在 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 模块作为执行某个目录zip 文件或其它 <a class="reference internal" href="../library/sys.html#sys.path" title="sys.path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path</span></code></a> 条目的一部分加载时被填充。</p>
<p><a class="reference internal" href="../using/cmdline.html#using-on-interface-options"><span class="std std-ref">其余的情况</span></a><code class="docutils literal notranslate"><span class="pre">__main__.__spec__</span></code> 会被设为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,因为用于填充 <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a> 的代码不直接与可导入的模块相对应:</p>
<ul class="simple">
<li><p>交互型提示</p></li>
<li><p><a class="reference internal" href="../using/cmdline.html#cmdoption-c"><code class="xref std std-option docutils literal notranslate"><span class="pre">-c</span></code></a> 选项</p></li>
<li><p>从 stdin 运行</p></li>
<li><p>直接从源码或字节码文件运行</p></li>
</ul>
<p>请注意在最后一种情况中 <code class="docutils literal notranslate"><span class="pre">__main__.__spec__</span></code> 总是为 <code class="docutils literal notranslate"><span class="pre">None</span></code><em>即使</em> 文件从技术上说可以作为一个模块被导入。 如果想要让 <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a> 中的元数据生效,请使用 <a class="reference internal" href="../using/cmdline.html#cmdoption-m"><code class="xref std std-option docutils literal notranslate"><span class="pre">-m</span></code></a> 开关。</p>
<p>还要注意即使是在 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 对应于一个可导入模块且 <code class="docutils literal notranslate"><span class="pre">__main__.__spec__</span></code> 被相应地设定时,它们仍会被视为 <em>不同的</em> 模块。 这是由于以下事实:使用 <code class="docutils literal notranslate"><span class="pre">if</span> <span class="pre">__name__</span> <span class="pre">==</span> <span class="pre">&quot;__main__&quot;:</span></code> 检测来保护的代码块仅会在模块被用来填充 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 命名空间时而非普通的导入时被执行。</p>
</section>
</section>
<section id="open-issues">
<h2><span class="section-number">5.9. </span>开放问题项<a class="headerlink" href="#open-issues" title="永久链接至标题"></a></h2>
<p>XXX 最好是能增加一个图表。</p>
<p>XXX * (import_machinery.rst) 是否要专门增加一节来说明模块和包的属性,也许可以扩展或移植数据模型参考页中的相关条目?</p>
<p>XXX 库手册中的 runpy 和 pkgutil 等等应该都在页面顶端增加指向新的导入系统章节的“另请参阅”链接。</p>
<p>XXX 是否要增加关于初始化 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 的不同方式的更多解释?</p>
<p>XXX 增加更多有关 <code class="docutils literal notranslate"><span class="pre">__main__</span></code> 怪异/坑人特性的信息 (例如直接从 <span class="target" id="index-54"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0395"><strong>PEP 395</strong></a> 复制)。</p>
</section>
<section id="references">
<h2><span class="section-number">5.10. </span>参考文献<a class="headerlink" href="#references" title="永久链接至标题"></a></h2>
<p>导入机制自 Python 诞生之初至今已发生了很大的变化。 原始的 <a class="reference external" href="https://www.python.org/doc/essays/packages/">包规格说明</a> 仍然可以查阅,但在撰写该文档之后许多相关细节已被修改。</p>
<p>原始的 <a class="reference internal" href="../library/sys.html#sys.meta_path" title="sys.meta_path"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.meta_path</span></code></a> 规格说明见 <span class="target" id="index-55"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0302"><strong>PEP 302</strong></a>,后续的扩展说明见 <span class="target" id="index-56"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0420"><strong>PEP 420</strong></a></p>
<p><span class="target" id="index-57"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0420"><strong>PEP 420</strong></a> 为 Python 3.3 引入了 <a class="reference internal" href="../glossary.html#term-namespace-package"><span class="xref std std-term">命名空间包</span></a><span class="target" id="index-58"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0420"><strong>PEP 420</strong></a> 还引入了 <code class="xref py py-meth docutils literal notranslate"><span class="pre">find_loader()</span></code> 协议作为 <code class="xref py py-meth docutils literal notranslate"><span class="pre">find_module()</span></code> 的替代。</p>
<p><span class="target" id="index-59"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0366"><strong>PEP 366</strong></a> 描述了新增的 <code class="docutils literal notranslate"><span class="pre">__package__</span></code> 属性,用于在模块中的显式相对导入。</p>
<p><span class="target" id="index-60"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0328"><strong>PEP 328</strong></a> 引入了绝对和显式相对导入,并初次提出了 <code class="docutils literal notranslate"><span class="pre">__name__</span></code> 语义,最终由 <span class="target" id="index-61"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0366"><strong>PEP 366</strong></a><code class="docutils literal notranslate"><span class="pre">__package__</span></code> 加入规范描述。</p>
<p><span class="target" id="index-62"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0338"><strong>PEP 338</strong></a> 定义了将模块作为脚本执行。</p>
<p><span class="target" id="index-63"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0451"><strong>PEP 451</strong></a> 在 spec 对象中增加了对每个模块导入状态的封装。 它还将加载器的大部分样板责任移交回导入机制中。 这些改变允许弃用导入系统中的一些 API 并为查找器和加载器增加一些新的方法。</p>
<p class="rubric">备注</p>
<dl class="footnote brackets">
<dt class="label" id="fnmo"><span class="brackets"><a class="fn-backref" href="#id1">1</a></span></dt>
<dd><p>参见 <a class="reference internal" href="../library/types.html#types.ModuleType" title="types.ModuleType"><code class="xref py py-class docutils literal notranslate"><span class="pre">types.ModuleType</span></code></a></p>
</dd>
<dt class="label" id="fnlo"><span class="brackets"><a class="fn-backref" href="#id3">2</a></span></dt>
<dd><p>importlib 实现避免直接使用返回值。 而是通过在 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中查找模块名称来获取模块对象。 这种方式的间接影响是被导入的模块可能在 <a class="reference internal" href="../library/sys.html#sys.modules" title="sys.modules"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.modules</span></code></a> 中替换其自身。 这属于具体实现的特定行为,不保证能在其他 Python 实现中起作用。</p>
</dd>
<dt class="label" id="fnpic"><span class="brackets"><a class="fn-backref" href="#id4">3</a></span></dt>
<dd><p>在遗留代码中,有可能在 <a class="reference internal" href="../library/sys.html#sys.path_importer_cache" title="sys.path_importer_cache"><code class="xref py py-data docutils literal notranslate"><span class="pre">sys.path_importer_cache</span></code></a> 中找到 <a class="reference internal" href="../library/imp.html#imp.NullImporter" title="imp.NullImporter"><code class="xref py py-class docutils literal notranslate"><span class="pre">imp.NullImporter</span></code></a> 的实例。 建议将这些代码修改为使用 <code class="docutils literal notranslate"><span class="pre">None</span></code> 代替。 详情参见 <a class="reference internal" href="../whatsnew/3.3.html#portingpythoncode"><span class="std std-ref">移植 Python 代码</span></a></p>
</dd>
</dl>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">5. 导入系统</a><ul>
<li><a class="reference internal" href="#importlib">5.1. <code class="xref py py-mod docutils literal notranslate"><span class="pre">importlib</span></code></a></li>
<li><a class="reference internal" href="#packages">5.2. 包</a><ul>
<li><a class="reference internal" href="#regular-packages">5.2.1. 常规包</a></li>
<li><a class="reference internal" href="#namespace-packages">5.2.2. 命名空间包</a></li>
</ul>
</li>
<li><a class="reference internal" href="#searching">5.3. 搜索</a><ul>
<li><a class="reference internal" href="#the-module-cache">5.3.1. 模块缓存</a></li>
<li><a class="reference internal" href="#finders-and-loaders">5.3.2. 查找器和加载器</a></li>
<li><a class="reference internal" href="#import-hooks">5.3.3. 导入钩子</a></li>
<li><a class="reference internal" href="#the-meta-path">5.3.4. 元路径</a></li>
</ul>
</li>
<li><a class="reference internal" href="#loading">5.4. 加载</a><ul>
<li><a class="reference internal" href="#loaders">5.4.1. 加载器</a></li>
<li><a class="reference internal" href="#submodules">5.4.2. 子模块</a></li>
<li><a class="reference internal" href="#module-spec">5.4.3. 模块规格说明</a></li>
<li><a class="reference internal" href="#import-related-module-attributes">5.4.4. 导入相关的模块属性</a></li>
<li><a class="reference internal" href="#module-path">5.4.5. module.__path__</a></li>
<li><a class="reference internal" href="#module-reprs">5.4.6. 模块的 repr</a></li>
<li><a class="reference internal" href="#cached-bytecode-invalidation">5.4.7. 已缓存字节码的失效</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-path-based-finder">5.5. 基于路径的查找器</a><ul>
<li><a class="reference internal" href="#path-entry-finders">5.5.1. 路径条目查找器</a></li>
<li><a class="reference internal" href="#path-entry-finder-protocol">5.5.2. 路径条目查找器协议</a></li>
</ul>
</li>
<li><a class="reference internal" href="#replacing-the-standard-import-system">5.6. 替换标准导入系统</a></li>
<li><a class="reference internal" href="#package-relative-imports">5.7. 包相对导入</a></li>
<li><a class="reference internal" href="#special-considerations-for-main">5.8. 有关 __main__ 的特殊事项</a><ul>
<li><a class="reference internal" href="#main-spec">5.8.1. __main__.__spec__</a></li>
</ul>
</li>
<li><a class="reference internal" href="#open-issues">5.9. 开放问题项</a></li>
<li><a class="reference internal" href="#references">5.10. 参考文献</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="executionmodel.html"
title="上一章"><span class="section-number">4. </span>执行模型</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="expressions.html"
title="下一章"><span class="section-number">6. </span>表达式</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/import.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="expressions.html" title="6. 表达式"
>下一页</a> |</li>
<li class="right" >
<a href="executionmodel.html" title="4. 执行模型"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>

View File

@@ -0,0 +1,350 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>Python语言参考 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="1. 概述" href="introduction.html" />
<link rel="prev" title="5. 编辑器和集成开发环境" href="../using/editors.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/index.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h4>上一个主题</h4>
<p class="topless"><a href="../using/editors.html"
title="上一章"><span class="section-number">5. </span>编辑器和集成开发环境</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="introduction.html"
title="下一章"><span class="section-number">1. </span>概述</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/index.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/index.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="introduction.html" title="1. 概述"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="../using/editors.html" title="5. 编辑器和集成开发环境"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="the-python-language-reference">
<span id="reference-index"></span><h1>Python语言参考<a class="headerlink" href="#the-python-language-reference" title="永久链接至标题"></a></h1>
<p>本参考手册描述了 Python 的语法和“核心语义”。本参考是简洁的,但试图做到准确和完整。 非必要的内建对象类型和内建函数、模块的语义描述在 <a class="reference internal" href="../library/index.html#library-index"><span class="std std-ref">Python 标准库</span></a> 中。有关该语言的非正式介绍,请参阅 <a class="reference internal" href="../tutorial/index.html#tutorial-index"><span class="std std-ref">Python 教程</span></a> 。对 C 或 C++ 程序员,还有两个额外的手册: <a class="reference internal" href="../extending/index.html#extending-index"><span class="std std-ref">扩展和嵌入 Python 解释器</span></a> 概述了如何编写一个 Python 扩展模块,<a class="reference internal" href="../c-api/index.html#c-api-index"><span class="std std-ref">Python/C API 参考手册</span></a> 详细介绍了 C/C++ 中可用的接口。</p>
<div class="toctree-wrapper compound">
<ul>
<li class="toctree-l1"><a class="reference internal" href="introduction.html">1. 概述</a><ul>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#alternate-implementations">1.1. 其他实现</a></li>
<li class="toctree-l2"><a class="reference internal" href="introduction.html#notation">1.2. 标注</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="lexical_analysis.html">2. 词法分析</a><ul>
<li class="toctree-l2"><a class="reference internal" href="lexical_analysis.html#line-structure">2.1. 行结构</a></li>
<li class="toctree-l2"><a class="reference internal" href="lexical_analysis.html#other-tokens">2.2. 其他形符</a></li>
<li class="toctree-l2"><a class="reference internal" href="lexical_analysis.html#identifiers">2.3. 标识符和关键字</a></li>
<li class="toctree-l2"><a class="reference internal" href="lexical_analysis.html#literals">2.4. 字面值</a></li>
<li class="toctree-l2"><a class="reference internal" href="lexical_analysis.html#operators">2.5. 运算符</a></li>
<li class="toctree-l2"><a class="reference internal" href="lexical_analysis.html#delimiters">2.6. 分隔符</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="datamodel.html">3. 数据模型</a><ul>
<li class="toctree-l2"><a class="reference internal" href="datamodel.html#objects-values-and-types">3.1. 对象、值与类型</a></li>
<li class="toctree-l2"><a class="reference internal" href="datamodel.html#the-standard-type-hierarchy">3.2. 标准类型层级结构</a></li>
<li class="toctree-l2"><a class="reference internal" href="datamodel.html#special-method-names">3.3. 特殊方法名称</a></li>
<li class="toctree-l2"><a class="reference internal" href="datamodel.html#coroutines">3.4. 协程</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="executionmodel.html">4. 执行模型</a><ul>
<li class="toctree-l2"><a class="reference internal" href="executionmodel.html#structure-of-a-program">4.1. 程序的结构</a></li>
<li class="toctree-l2"><a class="reference internal" href="executionmodel.html#naming-and-binding">4.2. 命名与绑定</a></li>
<li class="toctree-l2"><a class="reference internal" href="executionmodel.html#exceptions">4.3. 异常</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="import.html">5. 导入系统</a><ul>
<li class="toctree-l2"><a class="reference internal" href="import.html#importlib">5.1. <code class="xref py py-mod docutils literal notranslate"><span class="pre">importlib</span></code></a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#packages">5.2. 包</a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#searching">5.3. 搜索</a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#loading">5.4. 加载</a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#the-path-based-finder">5.5. 基于路径的查找器</a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#replacing-the-standard-import-system">5.6. 替换标准导入系统</a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#package-relative-imports">5.7. 包相对导入</a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#special-considerations-for-main">5.8. 有关 __main__ 的特殊事项</a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#open-issues">5.9. 开放问题项</a></li>
<li class="toctree-l2"><a class="reference internal" href="import.html#references">5.10. 参考文献</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="expressions.html">6. 表达式</a><ul>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#arithmetic-conversions">6.1. 算术转换</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#atoms">6.2. 原子</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#primaries">6.3. 原型</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#await-expression">6.4. await 表达式</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#the-power-operator">6.5. 幂运算符</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#unary-arithmetic-and-bitwise-operations">6.6. 一元算术和位运算</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#binary-arithmetic-operations">6.7. 二元算术运算符</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#shifting-operations">6.8. 移位运算</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#binary-bitwise-operations">6.9. 二元位运算</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#comparisons">6.10. 比较运算</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#boolean-operations">6.11. 布尔运算</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#assignment-expressions">6.12. 赋值表达式</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#conditional-expressions">6.13. 条件表达式</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#lambda">6.14. lambda 表达式</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#expression-lists">6.15. 表达式列表</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#evaluation-order">6.16. 求值顺序</a></li>
<li class="toctree-l2"><a class="reference internal" href="expressions.html#operator-precedence">6.17. 运算符优先级</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="simple_stmts.html">7. 简单语句</a><ul>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#expression-statements">7.1. 表达式语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#assignment-statements">7.2. 赋值语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-assert-statement">7.3. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">assert</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-pass-statement">7.4. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">pass</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-del-statement">7.5. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">del</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-return-statement">7.6. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-yield-statement">7.7. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-raise-statement">7.8. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-break-statement">7.9. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-continue-statement">7.10. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-import-statement">7.11. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-global-statement">7.12. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="simple_stmts.html#the-nonlocal-statement">7.13. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code> 语句</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="compound_stmts.html">8. 复合语句</a><ul>
<li class="toctree-l2"><a class="reference internal" href="compound_stmts.html#the-if-statement">8.1. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">if</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="compound_stmts.html#the-while-statement">8.2. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="compound_stmts.html#the-for-statement">8.3. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="compound_stmts.html#the-try-statement">8.4. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="compound_stmts.html#the-with-statement">8.5. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">with</span></code> 语句</a></li>
<li class="toctree-l2"><a class="reference internal" href="compound_stmts.html#function-definitions">8.6. 函数定义</a></li>
<li class="toctree-l2"><a class="reference internal" href="compound_stmts.html#class-definitions">8.7. 类定义</a></li>
<li class="toctree-l2"><a class="reference internal" href="compound_stmts.html#coroutines">8.8. 协程</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="toplevel_components.html">9. 最高层级组件</a><ul>
<li class="toctree-l2"><a class="reference internal" href="toplevel_components.html#complete-python-programs">9.1. 完整的 Python 程序</a></li>
<li class="toctree-l2"><a class="reference internal" href="toplevel_components.html#file-input">9.2. 文件输入</a></li>
<li class="toctree-l2"><a class="reference internal" href="toplevel_components.html#interactive-input">9.3. 交互式输入</a></li>
<li class="toctree-l2"><a class="reference internal" href="toplevel_components.html#expression-input">9.4. 表达式输入</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="grammar.html">10. 完整的语法规范</a></li>
</ul>
</div>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h4>上一个主题</h4>
<p class="topless"><a href="../using/editors.html"
title="上一章"><span class="section-number">5. </span>编辑器和集成开发环境</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="introduction.html"
title="下一章"><span class="section-number">1. </span>概述</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/index.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="introduction.html" title="1. 概述"
>下一页</a> |</li>
<li class="right" >
<a href="../using/editors.html" title="5. 编辑器和集成开发环境"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>

View File

@@ -0,0 +1,304 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>1. 概述 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="2. 词法分析" href="lexical_analysis.html" />
<link rel="prev" title="Python语言参考" href="index.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/introduction.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">1. 概述</a><ul>
<li><a class="reference internal" href="#alternate-implementations">1.1. 其他实现</a></li>
<li><a class="reference internal" href="#notation">1.2. 标注</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="index.html"
title="上一章">Python语言参考</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="lexical_analysis.html"
title="下一章"><span class="section-number">2. </span>词法分析</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/introduction.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/introduction.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="lexical_analysis.html" title="2. 词法分析"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="index.html" title="Python语言参考"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="introduction">
<span id="id1"></span><h1><span class="section-number">1. </span>概述<a class="headerlink" href="#introduction" title="永久链接至标题"></a></h1>
<p>本参考手册是对 Python 编程语言的描述。并不适宜作为教程使用。</p>
<p>我希望尽可能地保证内容精确无误,但还是选择使用自然词句进行描述,正式的规格定义仅用于句法和词法解析。这样应该能使文档对于普通人来说更易理解,但也可能导致一些歧义。因此,如果你是来自火星并且想凭借这份文档把 Python 重新实现一遍,也许有时需要自行猜测,实际上最终大概会得到一个十分不同的语言。而在另一方面,如果你正在使用 Python 并且想了解有关该语言特定领域的精确规则,你应该能够在这里找到它们。如果你希望查看对该语言更正式的定义,也许你可以花些时间自己写上一份 --- 或者发明一台克隆机器 :-)</p>
<p>在语言参考文档里加入过多的实现细节是很危险的 --- 具体实现可能发生改变对同一语言的其他实现可能使用不同的方式。而在另一方面CPython 是得到广泛使用的 Python 实现 (然而其他一些实现的拥护者也在增加),其中的特殊细节有时也值得一提,特别是当其实现方式导致额外的限制时。因此,你会发现在正文里不时会跳出来一些简短的 &quot;实现注释&quot;</p>
<p>每种 Python 实现都带有一些内置和标准的模块。相关的文档可参见 <a class="reference internal" href="../library/index.html#library-index"><span class="std std-ref">Python 标准库</span></a> 索引。少数内置模块也会在此提及,如果它们同语言描述存在明显的关联。</p>
<section id="alternate-implementations">
<span id="implementations"></span><h2><span class="section-number">1.1. </span>其他实现<a class="headerlink" href="#alternate-implementations" title="永久链接至标题"></a></h2>
<p>虽然官方 Python 实现差不多得到最广泛的欢迎,但也有一些其他实现对特定领域的用户来说更具吸引力。</p>
<p>知名的实现包括:</p>
<dl class="simple">
<dt>CPython</dt><dd><p>这是最早出现并持续维护的 Python 实现,以 C 语言编写。新的语言特性通常在此率先添加。</p>
</dd>
<dt>Jython</dt><dd><p>以 Java 语言编写的 Python 实现。此实现可以作为 Java 应用的一个脚本语言,或者可以用来创建需要 Java 类库支持的应用。想了解更多信息可访问 <a class="reference external" href="http://www.jython.org/">Jython 网站</a></p>
</dd>
<dt>Python for .NET</dt><dd><p>此实现实际上使用了 CPython 实现,但是属于 .NET 托管应用并且可以引入 .NET 类库。它的创造者是 Brian Lloyd。想了解详情可访问 <a class="reference external" href="https://pythonnet.github.io/">Python for .NET 主页</a></p>
</dd>
<dt>IronPython</dt><dd><p>另一个 .NET 的 Python 实现,与 Python.NET 不同点在于它是生成 IL 的完全 Python 实现,并且将 Python 代码直接编译为 .NET 程序集。它的创造者就是当初创造 Jython 的 Jim Hugunin。想了解详情可访问 <a class="reference external" href="http://ironpython.net/">IronPython 网站</a></p>
</dd>
<dt>PyPy</dt><dd><p>完全使用 Python 语言编写的 Python 实现。它支持多个其他实现所没有的高级特性,例如非栈式支持和 JIT 编译器等。此项目的目标之一是通过允许方便地修改解释器 (因为它是用 Python 编写的),鼓励该对语言本身进行试验。想了解详情可访问 <a class="reference external" href="http://pypy.org/">PyPy 项目主页</a></p>
</dd>
</dl>
<p>以上这些实现都可能在某些方面与此参考文档手册的描述有所差异,或是引入了超出标准 Python 文档范围的特定信息。请参考它们各自的专门文档,以确定你正在使用的这个实现有哪些你需要了解的东西。</p>
</section>
<section id="notation">
<span id="id2"></span><h2><span class="section-number">1.2. </span>标注<a class="headerlink" href="#notation" title="永久链接至标题"></a></h2>
<p id="index-0">句法和词法解析的描述采用经过改进的 BNF 语法标注。这包含以下定义样式:</p>
<pre>
<strong id="grammar-token-name">name </strong> ::= <a class="reference internal" href="#grammar-token-lc-letter"><code class="xref docutils literal notranslate"><span class="pre">lc_letter</span></code></a> (<a class="reference internal" href="#grammar-token-lc-letter"><code class="xref docutils literal notranslate"><span class="pre">lc_letter</span></code></a> | &quot;_&quot;)*
<strong id="grammar-token-lc-letter">lc_letter</strong> ::= &quot;a&quot;...&quot;z&quot;
</pre>
<p>第一行表示 <code class="docutils literal notranslate"><span class="pre">name</span></code> 是一个 <code class="docutils literal notranslate"><span class="pre">lc_letter</span></code> 之后跟零个或多个 <code class="docutils literal notranslate"><span class="pre">lc_letter</span></code> 和下划线。而一个 <code class="docutils literal notranslate"><span class="pre">lc_letter</span></code> 则是任意单个 <code class="docutils literal notranslate"><span class="pre">'a'</span></code><code class="docutils literal notranslate"><span class="pre">'z'</span></code> 字符。(实际上在本文档中始终采用此规则来定义词法和语法规则的名称。)</p>
<p>每条规则的开头是一个名称 (即该规则所定义的名称) 加上 <code class="docutils literal notranslate"><span class="pre">::=</span></code>。 竖线 (<code class="docutils literal notranslate"><span class="pre">|</span></code>) 被用来分隔可选项,它是此标注中绑定程度最低的操作符。 星号 (<code class="docutils literal notranslate"><span class="pre">*</span></code>) 表示前一项的零次或多次重复,类似地,加号 (<code class="docutils literal notranslate"><span class="pre">+</span></code>) 表示一次或多次重复,而由方括号括起的内容 (<code class="docutils literal notranslate"><span class="pre">[</span> <span class="pre">]</span></code>) 表示出现零次或一次 (或者说,这部分内容是可选的)。 <code class="docutils literal notranslate"><span class="pre">*</span></code><code class="docutils literal notranslate"><span class="pre">+</span></code> 操作符的绑定是最紧密的,圆括号用于分组。 字符串字面值包含在引号内。 空格的作用仅限于分隔形符。 每条规则通常为一行,有许多个可选项的规则可能会以竖线为界分为多行。</p>
<p id="index-1">在词法定义中 (如上述示例),还额外使用了两个约定: 由三个点号分隔的两个字符字面值表示在指定 (闭) 区间范围内的任意单个 ASCII 字符。由尖括号 (<code class="docutils literal notranslate"><span class="pre">&lt;...&gt;</span></code>) 括起来的内容是对于所定义符号的非正式描述;即可以在必要时用来说明 '控制字符' 的意图。</p>
<p>虽然所用的标注方式几乎相同,但是词法定义和句法定义是存在很大区别的: 词法定义作用于输入源中单独的字符,而句法定义则作用于由词法分析所生成的形符流。在下一章节 (&quot;词法分析&quot;) 中使用的 BNF 全部都是词法定义;在之后的章节中使用的则是句法定义。</p>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">1. 概述</a><ul>
<li><a class="reference internal" href="#alternate-implementations">1.1. 其他实现</a></li>
<li><a class="reference internal" href="#notation">1.2. 标注</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="index.html"
title="上一章">Python语言参考</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="lexical_analysis.html"
title="下一章"><span class="section-number">2. </span>词法分析</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/introduction.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="lexical_analysis.html" title="2. 词法分析"
>下一页</a> |</li>
<li class="right" >
<a href="index.html" title="Python语言参考"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>

View File

@@ -0,0 +1,841 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>2. 词法分析 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="3. 数据模型" href="datamodel.html" />
<link rel="prev" title="1. 概述" href="introduction.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/lexical_analysis.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">2. 词法分析</a><ul>
<li><a class="reference internal" href="#line-structure">2.1. 行结构</a><ul>
<li><a class="reference internal" href="#logical-lines">2.1.1. 逻辑行</a></li>
<li><a class="reference internal" href="#physical-lines">2.1.2. 物理行</a></li>
<li><a class="reference internal" href="#comments">2.1.3. 注释</a></li>
<li><a class="reference internal" href="#encoding-declarations">2.1.4. 编码声明</a></li>
<li><a class="reference internal" href="#explicit-line-joining">2.1.5. 显式拼接行</a></li>
<li><a class="reference internal" href="#implicit-line-joining">2.1.6. 隐式拼接行</a></li>
<li><a class="reference internal" href="#blank-lines">2.1.7. 空白行</a></li>
<li><a class="reference internal" href="#indentation">2.1.8. 缩进</a></li>
<li><a class="reference internal" href="#whitespace-between-tokens">2.1.9. 形符间的空白字符</a></li>
</ul>
</li>
<li><a class="reference internal" href="#other-tokens">2.2. 其他形符</a></li>
<li><a class="reference internal" href="#identifiers">2.3. 标识符和关键字</a><ul>
<li><a class="reference internal" href="#keywords">2.3.1. 关键字</a></li>
<li><a class="reference internal" href="#reserved-classes-of-identifiers">2.3.2. 保留的标识符类</a></li>
</ul>
</li>
<li><a class="reference internal" href="#literals">2.4. 字面值</a><ul>
<li><a class="reference internal" href="#string-and-bytes-literals">2.4.1. 字符串与字节串字面值</a></li>
<li><a class="reference internal" href="#string-literal-concatenation">2.4.2. 字符串字面值合并</a></li>
<li><a class="reference internal" href="#formatted-string-literals">2.4.3. 格式字符串字面值</a></li>
<li><a class="reference internal" href="#numeric-literals">2.4.4. 数值字面值</a></li>
<li><a class="reference internal" href="#integer-literals">2.4.5. 整数字面值</a></li>
<li><a class="reference internal" href="#floating-point-literals">2.4.6. 浮点数字面值</a></li>
<li><a class="reference internal" href="#imaginary-literals">2.4.7. 虚数字面值</a></li>
</ul>
</li>
<li><a class="reference internal" href="#operators">2.5. 运算符</a></li>
<li><a class="reference internal" href="#delimiters">2.6. 分隔符</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="introduction.html"
title="上一章"><span class="section-number">1. </span>概述</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="datamodel.html"
title="下一章"><span class="section-number">3. </span>数据模型</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/lexical_analysis.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/lexical_analysis.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="datamodel.html" title="3. 数据模型"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="introduction.html" title="1. 概述"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="lexical-analysis">
<span id="lexical"></span><h1><span class="section-number">2. </span>词法分析<a class="headerlink" href="#lexical-analysis" title="永久链接至标题"></a></h1>
<p id="index-0">Python 程序由 <em>解析器</em> 读取,输入解析器的是 <em>词法分析器</em> 生成的 <em>形符</em> 流。本章介绍词法分析器怎样把文件拆成形符。</p>
<p>Python 将读取的程序文本转为 Unicode 代码点;编码声明用于指定源文件的编码,默认为 UTF-8详见 <span class="target" id="index-37"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3120"><strong>PEP 3120</strong></a>。源文件不能解码时,触发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a></p>
<section id="line-structure">
<span id="id1"></span><h2><span class="section-number">2.1. </span>行结构<a class="headerlink" href="#line-structure" title="永久链接至标题"></a></h2>
<p id="index-2">Python 程序可以拆分为多个 <em>逻辑行</em></p>
<section id="logical-lines">
<span id="id2"></span><h3><span class="section-number">2.1.1. </span>逻辑行<a class="headerlink" href="#logical-lines" title="永久链接至标题"></a></h3>
<p id="index-3">NEWLINE 形符表示结束逻辑行。语句不能超出逻辑行的边界,除非句法支持 NEWLINE (例如,复合语句中的多行子语句)。根据显式或隐式 <em>行拼接</em> 规则,一个或多个 <em>物理行</em> 可组成逻辑行。</p>
</section>
<section id="physical-lines">
<span id="id3"></span><h3><span class="section-number">2.1.2. </span>物理行<a class="headerlink" href="#physical-lines" title="永久链接至标题"></a></h3>
<p>物理行是一序列字符,由行尾序列终止。源文件和字符串可使用任意标准平台行终止序列 - Unix ASCII 字符 LF (换行)、 Windows ASCII 字符序列 CR LF (回车换行)、或老式 Macintosh ASCII 字符 CR (回车)。不管在哪个平台,这些形式均可等价使用。输入结束也可以用作最终物理行的隐式终止符。</p>
<p>嵌入 Python 时,传入 Python API 的源码字符串应使用 C 标准惯例换行符(<code class="docutils literal notranslate"><span class="pre">\n</span></code>,代表 ASCII 字符 LF 行终止符)。</p>
</section>
<section id="comments">
<span id="id4"></span><h3><span class="section-number">2.1.3. </span>注释<a class="headerlink" href="#comments" title="永久链接至标题"></a></h3>
<p id="index-4">注释以井号 <code class="docutils literal notranslate"><span class="pre">#</span></code> 开头,在物理行末尾截止。注意,井号不是字符串字面值。除非应用隐式行拼接规则,否则,注释代表逻辑行结束。句法不解析注释。</p>
</section>
<section id="encoding-declarations">
<span id="encodings"></span><h3><span class="section-number">2.1.4. </span>编码声明<a class="headerlink" href="#encoding-declarations" title="永久链接至标题"></a></h3>
<p id="index-5">Python 脚本第一或第二行的注释匹配正则表达式 <code class="docutils literal notranslate"><span class="pre">coding[=:]\s*([-\w.]+)</span></code> 时,该注释会被当作编码声明;这个表达式的第一组指定了源码文件的编码。编码声明必须独占一行,在第二行时,则第一行必须也是注释。编码表达式的形式如下:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># -*- coding: &lt;encoding-name&gt; -*-</span>
</pre></div>
</div>
<p>这也是 GNU Emacs 认可的形式,此外,还支持如下形式:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="c1"># vim:fileencoding=&lt;encoding-name&gt;</span>
</pre></div>
</div>
<p>这是 Bram Moolenaar 的 VIM 认可的形式。</p>
<p>没有编码声明时,默认编码为 UTF-8。此外如果文件的首字节为 UTF-8 字节顺序标志(<code class="docutils literal notranslate"><span class="pre">b'\xef\xbb\xbf'</span></code>),文件编码也声明为 UTF-8这是 Microsoft 的 <strong class="program">notepad</strong> 等软件支持的形式)。</p>
<p>编码声明指定的编码名称必须是 Python 所认可的编码。所有词法分析将使用此编码,包括语义字符串、注释和标识符。</p>
</section>
<section id="explicit-line-joining">
<span id="explicit-joining"></span><h3><span class="section-number">2.1.5. </span>显式拼接行<a class="headerlink" href="#explicit-line-joining" title="永久链接至标题"></a></h3>
<p id="index-6">两个及两个以上的物理行可用反斜杠(<code class="docutils literal notranslate"><span class="pre">\</span></code>)拼接为一个逻辑行,规则如下:以不在字符串或注释内的反斜杠结尾时,物理行将与下一行拼接成一个逻辑行,并删除反斜杠及其后的换行符。例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="mi">1900</span> <span class="o">&lt;</span> <span class="n">year</span> <span class="o">&lt;</span> <span class="mi">2100</span> <span class="ow">and</span> <span class="mi">1</span> <span class="o">&lt;=</span> <span class="n">month</span> <span class="o">&lt;=</span> <span class="mi">12</span> \
<span class="ow">and</span> <span class="mi">1</span> <span class="o">&lt;=</span> <span class="n">day</span> <span class="o">&lt;=</span> <span class="mi">31</span> <span class="ow">and</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">hour</span> <span class="o">&lt;</span> <span class="mi">24</span> \
<span class="ow">and</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">minute</span> <span class="o">&lt;</span> <span class="mi">60</span> <span class="ow">and</span> <span class="mi">0</span> <span class="o">&lt;=</span> <span class="n">second</span> <span class="o">&lt;</span> <span class="mi">60</span><span class="p">:</span> <span class="c1"># Looks like a valid date</span>
<span class="k">return</span> <span class="mi">1</span>
</pre></div>
</div>
<p>以反斜杠结尾的行,不能加注释;反斜杠也不能拼接注释。除字符串字面值外,反斜杠不能拼接形符(如,除字符串字面值外,不能用反斜杠把形符切分至两个物理行)。反斜杠只能在代码的字符串字面值里,在其他任何位置都是非法的。</p>
</section>
<section id="implicit-line-joining">
<span id="implicit-joining"></span><h3><span class="section-number">2.1.6. </span>隐式拼接行<a class="headerlink" href="#implicit-line-joining" title="永久链接至标题"></a></h3>
<p>圆括号、方括号、花括号内的表达式可以分成多个物理行,不必使用反斜杠。例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">month_names</span> <span class="o">=</span> <span class="p">[</span><span class="s1">&#39;Januari&#39;</span><span class="p">,</span> <span class="s1">&#39;Februari&#39;</span><span class="p">,</span> <span class="s1">&#39;Maart&#39;</span><span class="p">,</span> <span class="c1"># These are the</span>
<span class="s1">&#39;April&#39;</span><span class="p">,</span> <span class="s1">&#39;Mei&#39;</span><span class="p">,</span> <span class="s1">&#39;Juni&#39;</span><span class="p">,</span> <span class="c1"># Dutch names</span>
<span class="s1">&#39;Juli&#39;</span><span class="p">,</span> <span class="s1">&#39;Augustus&#39;</span><span class="p">,</span> <span class="s1">&#39;September&#39;</span><span class="p">,</span> <span class="c1"># for the months</span>
<span class="s1">&#39;Oktober&#39;</span><span class="p">,</span> <span class="s1">&#39;November&#39;</span><span class="p">,</span> <span class="s1">&#39;December&#39;</span><span class="p">]</span> <span class="c1"># of the year</span>
</pre></div>
</div>
<p>隐式行拼接可含注释;后续行的缩进并不重要;还支持空的后续行。隐式拼接行之间没有 NEWLINE 形符。三引号字符串支持隐式拼接行(见下文),但不支持注释。</p>
</section>
<section id="blank-lines">
<span id="id5"></span><h3><span class="section-number">2.1.7. </span>空白行<a class="headerlink" href="#blank-lines" title="永久链接至标题"></a></h3>
<p id="index-7">只包含空格符、制表符、换页符、注释的逻辑行会被忽略(即不生成 NEWLINE 形符)。交互模式输入语句时,空白行的处理方式可能因读取 - 求值 - 打印循环REPL的具体实现方式而不同。标准交互模式解释器中完全空白的逻辑行即连空格或注释都没有将结束多行复合语句。</p>
</section>
<section id="indentation">
<span id="id6"></span><h3><span class="section-number">2.1.8. </span>缩进<a class="headerlink" href="#indentation" title="永久链接至标题"></a></h3>
<p id="index-8">逻辑行开头的空白符(空格符和制表符)用于计算该行的缩进层级,决定语句组块。</p>
<p>制表符(从左至右)被替换为一至八个空格,缩进空格的总数是八的倍数(与 Unix 的规则保持一致)。首个非空字符前的空格数决定了该行的缩进层次。缩进不能用反斜杠进行多行拼接;首个反斜杠之前的空白符决定了缩进的层次。</p>
<p>源文件混用制表符和空格符缩进时,因空格数量与制表符相关,由此产生的不一致将导致不能正常识别缩进层次,从而触发 <a class="reference internal" href="../library/exceptions.html#TabError" title="TabError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TabError</span></code></a></p>
<p><strong>跨平台兼容性说明:</strong> 鉴于非 UNIX 平台文本编辑器本身的特性,请勿在源文件中混用制表符和空格符。另外也请注意,不同平台有可能会显式限制最大缩进层级。</p>
<p>行首含换页符时,缩进计算将忽略该换页符。换页符在行首空白符内其他位置的效果未定义(例如,可能导致空格计数重置为零)。</p>
<p id="index-9">连续行的缩进层级以堆栈形式生成 INDENT 和 DEDENT 形符,说明如下。</p>
<p>读取文件第一行前,先向栈推入一个零值,该零值不会被移除。推入栈的层级值从底至顶持续增加。每个逻辑行开头的行缩进层级将与栈顶行比较。如果相等,则不做处理。如果新行层级较高,则会被推入栈顶,并生成一个 INDENT 形符。如果新行层级较低,则 <em>应当</em> 是栈中的层级数值之一;栈中高于该层级的所有数值都将被移除,每移除一级数值生成一个 DEDENT 形符。文件末尾,栈中剩余的每个大于零的数值生成一个 DEDENT 形符。</p>
<p>下面的 Python 代码缩进示例虽然正确,但含混不清:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">perm</span><span class="p">(</span><span class="n">l</span><span class="p">):</span>
<span class="c1"># Compute the list of all permutations of l</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">l</span><span class="p">)</span> <span class="o">&lt;=</span> <span class="mi">1</span><span class="p">:</span>
<span class="k">return</span> <span class="p">[</span><span class="n">l</span><span class="p">]</span>
<span class="n">r</span> <span class="o">=</span> <span class="p">[]</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">l</span><span class="p">)):</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">l</span><span class="p">[:</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">l</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">perm</span><span class="p">(</span><span class="n">s</span><span class="p">)</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">p</span><span class="p">:</span>
<span class="n">r</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">l</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">x</span><span class="p">)</span>
<span class="k">return</span> <span class="n">r</span>
</pre></div>
</div>
<p>下例展示了多种缩进错误:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span> <span class="k">def</span> <span class="nf">perm</span><span class="p">(</span><span class="n">l</span><span class="p">):</span> <span class="c1"># error: first line indented</span>
<span class="k">for</span> <span class="n">i</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="nb">len</span><span class="p">(</span><span class="n">l</span><span class="p">)):</span> <span class="c1"># error: not indented</span>
<span class="n">s</span> <span class="o">=</span> <span class="n">l</span><span class="p">[:</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">l</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">:]</span>
<span class="n">p</span> <span class="o">=</span> <span class="n">perm</span><span class="p">(</span><span class="n">l</span><span class="p">[:</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">l</span><span class="p">[</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">:])</span> <span class="c1"># error: unexpected indent</span>
<span class="k">for</span> <span class="n">x</span> <span class="ow">in</span> <span class="n">p</span><span class="p">:</span>
<span class="n">r</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">l</span><span class="p">[</span><span class="n">i</span><span class="p">:</span><span class="n">i</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">+</span> <span class="n">x</span><span class="p">)</span>
<span class="k">return</span> <span class="n">r</span> <span class="c1"># error: inconsistent dedent</span>
</pre></div>
</div>
<p>(实际上,解析器可以识别前三个错误;只有最后一个错误由词法分析器识别 --- <code class="docutils literal notranslate"><span class="pre">return</span> <span class="pre">r</span></code> 的缩进无法匹配从栈里移除的缩进层级。)</p>
</section>
<section id="whitespace-between-tokens">
<span id="whitespace"></span><h3><span class="section-number">2.1.9. </span>形符间的空白字符<a class="headerlink" href="#whitespace-between-tokens" title="永久链接至标题"></a></h3>
<p>除非在逻辑行开头或字符串内空格符、制表符、换页符等空白符都可以分隔形符。要把两个相连形符解读为不同形符需要用空白符分隔例如ab 是一个形符a b 则是两个形符)。</p>
</section>
</section>
<section id="other-tokens">
<span id="id7"></span><h2><span class="section-number">2.2. </span>其他形符<a class="headerlink" href="#other-tokens" title="永久链接至标题"></a></h2>
<p>除 NEWLINE、INDENT、DEDENT 外,还有 <em>标识符</em><em>关键字</em><em>字面值</em><em>运算符</em><em>分隔符</em> 等形符。 空白符(前述的行终止符除外)不是形符,可用于分隔形符。存在二义性时,将从左至右,读取尽量长的字符串组成合法形符。</p>
</section>
<section id="identifiers">
<span id="identifiers-and-keywords"></span><h2><span class="section-number">2.3. </span>标识符和关键字<a class="headerlink" href="#identifiers" title="永久链接至标题"></a></h2>
<p id="index-10">标识符(也称为 <em>名称</em>)的词法定义说明如下。</p>
<p>Python 标识符的句法基于 Unicode 标准附件 UAX-31并加入了下文定义的细化与修改详见 <span class="target" id="index-38"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3131"><strong>PEP 3131</strong></a></p>
<p>与 Python 2.x 一样,在 ASCII 范围内U+0001..U+007F有效标识符字符为 大小写字母 <code class="docutils literal notranslate"><span class="pre">A</span></code><code class="docutils literal notranslate"><span class="pre">Z</span></code>、下划线 <code class="docutils literal notranslate"><span class="pre">_</span></code> 、数字 <code class="docutils literal notranslate"><span class="pre">0</span></code><code class="docutils literal notranslate"><span class="pre">9</span></code>,但不能以数字开头。</p>
<p>Python 3.0 引入了 ASCII 之外的更多字符(请参阅 <span class="target" id="index-39"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3131"><strong>PEP 3131</strong></a>)。这些字符的分类使用 <a class="reference internal" href="../library/unicodedata.html#module-unicodedata" title="unicodedata: Access the Unicode Database."><code class="xref py py-mod docutils literal notranslate"><span class="pre">unicodedata</span></code></a> 模块中的 Unicode 字符数据库版本。</p>
<p>标识符的长度没有限制,但区分大小写。</p>
<pre>
<strong id="grammar-token-identifier">identifier </strong> ::= <a class="reference internal" href="#grammar-token-xid-start"><code class="xref docutils literal notranslate"><span class="pre">xid_start</span></code></a> <a class="reference internal" href="#grammar-token-xid-continue"><code class="xref docutils literal notranslate"><span class="pre">xid_continue</span></code></a>*
<strong id="grammar-token-id-start">id_start </strong> ::= &lt;all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property&gt;
<strong id="grammar-token-id-continue">id_continue </strong> ::= &lt;all characters in <a class="reference internal" href="#grammar-token-id-start"><code class="xref docutils literal notranslate"><span class="pre">id_start</span></code></a>, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property&gt;
<strong id="grammar-token-xid-start">xid_start </strong> ::= &lt;all characters in <a class="reference internal" href="#grammar-token-id-start"><code class="xref docutils literal notranslate"><span class="pre">id_start</span></code></a> whose NFKC normalization is in &quot;id_start xid_continue*&quot;&gt;
<strong id="grammar-token-xid-continue">xid_continue</strong> ::= &lt;all characters in <a class="reference internal" href="#grammar-token-id-continue"><code class="xref docutils literal notranslate"><span class="pre">id_continue</span></code></a> whose NFKC normalization is in &quot;id_continue*&quot;&gt;
</pre>
<p>上述 Unicode 类别码的含义:</p>
<ul class="simple">
<li><p><em>Lu</em> - 大写字母</p></li>
<li><p><em>Ll</em> - 小写字母</p></li>
<li><p><em>Lt</em> - 词首大写字母</p></li>
<li><p><em>Lm</em> - 修饰符字母</p></li>
<li><p><em>Lo</em> - 其他字母</p></li>
<li><p><em>Nl</em> - 字母数字</p></li>
<li><p><em>Mn</em> - 非空白标识</p></li>
<li><p><em>Mc</em> - 含空白标识</p></li>
<li><p><em>Nd</em> - 十进制数字</p></li>
<li><p><em>Pc</em> - 连接标点</p></li>
<li><p><em>Other_ID_Start</em> - 由 <a class="reference external" href="http://www.unicode.org/Public/12.1.0/ucd/PropList.txt">PropList.txt</a> 定义的显式字符列表,用来支持向下兼容</p></li>
<li><p><em>Other_ID_Continue</em> - 同上</p></li>
</ul>
<p>在解析时,所有标识符都会被转换为规范形式 NFKC标识符的比较都是基于 NFKC。</p>
<p>Unicode 4.1 中所有可用的标识符字符详见此 HTML 文件 <a class="reference external" href="https://www.unicode.org/Public/13.0.0/ucd/DerivedCoreProperties.txt">https://www.unicode.org/Public/13.0.0/ucd/DerivedCoreProperties.txt</a></p>
<section id="keywords">
<span id="id8"></span><h3><span class="section-number">2.3.1. </span>关键字<a class="headerlink" href="#keywords" title="永久链接至标题"></a></h3>
<p id="index-13">以下标识符为保留字,或称 <em>关键字</em>,不可用于普通标识符。关键字的拼写必须与这里列出的完全一致:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>False await else import pass
None break except in raise
True class finally is return
and continue for lambda try
as def from nonlocal while
assert del global not with
async elif if or yield
</pre></div>
</div>
</section>
<section id="reserved-classes-of-identifiers">
<span id="id-classes"></span><span id="index-14"></span><h3><span class="section-number">2.3.2. </span>保留的标识符类<a class="headerlink" href="#reserved-classes-of-identifiers" title="永久链接至标题"></a></h3>
<p>某些标识符类(除了关键字)具有特殊含义。这些类的命名模式以下划线字符开头,并以下划线结尾:</p>
<dl>
<dt><code class="docutils literal notranslate"><span class="pre">_*</span></code></dt><dd><p><code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">module</span> <span class="pre">import</span> <span class="pre">*</span></code> 时,不会导入。交互式解释器中,特殊标识符 <code class="docutils literal notranslate"><span class="pre">_</span></code> 用于存储最近一次求值的结果;该标识符保存在 <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a> 模块里。不处于交互模式时,<code class="docutils literal notranslate"><span class="pre">_</span></code> 没有特殊含义,也没有预定义。详见 <a class="reference internal" href="simple_stmts.html#import"><span class="std std-ref">import 语句</span></a></p>
<div class="admonition note">
<p class="admonition-title">注解</p>
<p><code class="docutils literal notranslate"><span class="pre">_</span></code> 常用于连接国际化文本;详见 <a class="reference internal" href="../library/gettext.html#module-gettext" title="gettext: Multilingual internationalization services."><code class="xref py py-mod docutils literal notranslate"><span class="pre">gettext</span></code></a> 模块文档。</p>
</div>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">__*__</span></code></dt><dd><p>系统定义的名称,通常简称为 &quot;dunder&quot; 。这些名称由解释器及其实现(包括标准库)定义。现有系统定义名称相关的论述详见 <a class="reference internal" href="datamodel.html#specialnames"><span class="std std-ref">特殊方法名称</span></a> 等章节。Python 未来版本中还将定义更多此类名称。任何情况下,<em>任何</em> 不显式遵从 <code class="docutils literal notranslate"><span class="pre">__*__</span></code> 名称的文档用法,都可能导致无警告提示的错误。</p>
</dd>
<dt><code class="docutils literal notranslate"><span class="pre">__*</span></code></dt><dd><p>类的私有名称。类定义时,此类名称以一种混合形式重写,以避免基类及派生类的 &quot;私有&quot; 属性之间产生名称冲突。详见 <a class="reference internal" href="expressions.html#atom-identifiers"><span class="std std-ref">标识符(名称)</span></a></p>
</dd>
</dl>
</section>
</section>
<section id="literals">
<span id="id9"></span><h2><span class="section-number">2.4. </span>字面值<a class="headerlink" href="#literals" title="永久链接至标题"></a></h2>
<p id="index-15">字面值是内置类型常量值的表示法。</p>
<section id="string-and-bytes-literals">
<span id="strings"></span><span id="index-16"></span><h3><span class="section-number">2.4.1. </span>字符串与字节串字面值<a class="headerlink" href="#string-and-bytes-literals" title="永久链接至标题"></a></h3>
<p>字符串字面值的词法定义如下:</p>
<pre>
<strong id="grammar-token-stringliteral">stringliteral </strong> ::= [<a class="reference internal" href="#grammar-token-stringprefix"><code class="xref docutils literal notranslate"><span class="pre">stringprefix</span></code></a>](<a class="reference internal" href="#grammar-token-shortstring"><code class="xref docutils literal notranslate"><span class="pre">shortstring</span></code></a> | <a class="reference internal" href="#grammar-token-longstring"><code class="xref docutils literal notranslate"><span class="pre">longstring</span></code></a>)
<strong id="grammar-token-stringprefix">stringprefix </strong> ::= &quot;r&quot; | &quot;u&quot; | &quot;R&quot; | &quot;U&quot; | &quot;f&quot; | &quot;F&quot;
| &quot;fr&quot; | &quot;Fr&quot; | &quot;fR&quot; | &quot;FR&quot; | &quot;rf&quot; | &quot;rF&quot; | &quot;Rf&quot; | &quot;RF&quot;
<strong id="grammar-token-shortstring">shortstring </strong> ::= &quot;'&quot; <a class="reference internal" href="#grammar-token-shortstringitem"><code class="xref docutils literal notranslate"><span class="pre">shortstringitem</span></code></a>* &quot;'&quot; | '&quot;' <a class="reference internal" href="#grammar-token-shortstringitem"><code class="xref docutils literal notranslate"><span class="pre">shortstringitem</span></code></a>* '&quot;'
<strong id="grammar-token-longstring">longstring </strong> ::= &quot;'''&quot; <a class="reference internal" href="#grammar-token-longstringitem"><code class="xref docutils literal notranslate"><span class="pre">longstringitem</span></code></a>* &quot;'''&quot; | '&quot;&quot;&quot;' <a class="reference internal" href="#grammar-token-longstringitem"><code class="xref docutils literal notranslate"><span class="pre">longstringitem</span></code></a>* '&quot;&quot;&quot;'
<strong id="grammar-token-shortstringitem">shortstringitem</strong> ::= <a class="reference internal" href="#grammar-token-shortstringchar"><code class="xref docutils literal notranslate"><span class="pre">shortstringchar</span></code></a> | <a class="reference internal" href="#grammar-token-stringescapeseq"><code class="xref docutils literal notranslate"><span class="pre">stringescapeseq</span></code></a>
<strong id="grammar-token-longstringitem">longstringitem </strong> ::= <a class="reference internal" href="#grammar-token-longstringchar"><code class="xref docutils literal notranslate"><span class="pre">longstringchar</span></code></a> | <a class="reference internal" href="#grammar-token-stringescapeseq"><code class="xref docutils literal notranslate"><span class="pre">stringescapeseq</span></code></a>
<strong id="grammar-token-shortstringchar">shortstringchar</strong> ::= &lt;any source character except &quot;\&quot; or newline or the quote&gt;
<strong id="grammar-token-longstringchar">longstringchar </strong> ::= &lt;any source character except &quot;\&quot;&gt;
<strong id="grammar-token-stringescapeseq">stringescapeseq</strong> ::= &quot;\&quot; &lt;any source character&gt;
</pre>
<pre>
<strong id="grammar-token-bytesliteral">bytesliteral </strong> ::= <a class="reference internal" href="#grammar-token-bytesprefix"><code class="xref docutils literal notranslate"><span class="pre">bytesprefix</span></code></a>(<a class="reference internal" href="#grammar-token-shortbytes"><code class="xref docutils literal notranslate"><span class="pre">shortbytes</span></code></a> | <a class="reference internal" href="#grammar-token-longbytes"><code class="xref docutils literal notranslate"><span class="pre">longbytes</span></code></a>)
<strong id="grammar-token-bytesprefix">bytesprefix </strong> ::= &quot;b&quot; | &quot;B&quot; | &quot;br&quot; | &quot;Br&quot; | &quot;bR&quot; | &quot;BR&quot; | &quot;rb&quot; | &quot;rB&quot; | &quot;Rb&quot; | &quot;RB&quot;
<strong id="grammar-token-shortbytes">shortbytes </strong> ::= &quot;'&quot; <a class="reference internal" href="#grammar-token-shortbytesitem"><code class="xref docutils literal notranslate"><span class="pre">shortbytesitem</span></code></a>* &quot;'&quot; | '&quot;' <a class="reference internal" href="#grammar-token-shortbytesitem"><code class="xref docutils literal notranslate"><span class="pre">shortbytesitem</span></code></a>* '&quot;'
<strong id="grammar-token-longbytes">longbytes </strong> ::= &quot;'''&quot; <a class="reference internal" href="#grammar-token-longbytesitem"><code class="xref docutils literal notranslate"><span class="pre">longbytesitem</span></code></a>* &quot;'''&quot; | '&quot;&quot;&quot;' <a class="reference internal" href="#grammar-token-longbytesitem"><code class="xref docutils literal notranslate"><span class="pre">longbytesitem</span></code></a>* '&quot;&quot;&quot;'
<strong id="grammar-token-shortbytesitem">shortbytesitem</strong> ::= <a class="reference internal" href="#grammar-token-shortbyteschar"><code class="xref docutils literal notranslate"><span class="pre">shortbyteschar</span></code></a> | <a class="reference internal" href="#grammar-token-bytesescapeseq"><code class="xref docutils literal notranslate"><span class="pre">bytesescapeseq</span></code></a>
<strong id="grammar-token-longbytesitem">longbytesitem </strong> ::= <a class="reference internal" href="#grammar-token-longbyteschar"><code class="xref docutils literal notranslate"><span class="pre">longbyteschar</span></code></a> | <a class="reference internal" href="#grammar-token-bytesescapeseq"><code class="xref docutils literal notranslate"><span class="pre">bytesescapeseq</span></code></a>
<strong id="grammar-token-shortbyteschar">shortbyteschar</strong> ::= &lt;any ASCII character except &quot;\&quot; or newline or the quote&gt;
<strong id="grammar-token-longbyteschar">longbyteschar </strong> ::= &lt;any ASCII character except &quot;\&quot;&gt;
<strong id="grammar-token-bytesescapeseq">bytesescapeseq</strong> ::= &quot;\&quot; &lt;any ASCII character&gt;
</pre>
<p>上述产生式没有说明以下句法限制,<a class="reference internal" href="#grammar-token-stringprefix"><code class="xref std std-token docutils literal notranslate"><span class="pre">stringprefix</span></code></a><a class="reference internal" href="#grammar-token-bytesprefix"><code class="xref std std-token docutils literal notranslate"><span class="pre">bytesprefix</span></code></a> 与其他字面值之间不允许有空白符。源字符集由编码声明定义;源文件没有编码声明时,默认为 UTF-8详见 <a class="reference internal" href="#encodings"><span class="std std-ref">编码声明</span></a></p>
<p id="index-17">自然语言描述: 两种字面值都可以用成对单引号 (<code class="docutils literal notranslate"><span class="pre">'</span></code>) 或双引号 (<code class="docutils literal notranslate"><span class="pre">&quot;</span></code>) 来标示首尾。它们也可以用成对的连续三个单引号或双引号来标示首尾 (这通常被称为 <em>三引号字符串</em>)。反斜杠 (<code class="docutils literal notranslate"><span class="pre">\</span></code>) 字符被用来对特殊含义的字符进行转义,例如换行,反斜杠本身或是引号等字符。</p>
<p id="index-18">字节串字面值要加前缀 <code class="docutils literal notranslate"><span class="pre">'b'</span></code><code class="docutils literal notranslate"><span class="pre">'B'</span></code>;生成的是类型 <a class="reference internal" href="../library/stdtypes.html#bytes" title="bytes"><code class="xref py py-class docutils literal notranslate"><span class="pre">bytes</span></code></a> 的实例,不是类型 <a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-class docutils literal notranslate"><span class="pre">str</span></code></a> 的实例;字节串只能包含 ASCII 字符;字节串数值大于等于 128 时,必须用转义表示。</p>
<p id="index-19">字符串和字节串都可以加前缀 <code class="docutils literal notranslate"><span class="pre">'r'</span></code><code class="docutils literal notranslate"><span class="pre">'R'</span></code>,称为 <em class="dfn">原始字符串</em>,原始字符串把反斜杠当作原义字符,不执行转义操作。因此,原始字符串不转义 <code class="docutils literal notranslate"><span class="pre">'\U'</span></code><code class="docutils literal notranslate"><span class="pre">'\u'</span></code>。与 Python 2.x 的原始 unicode 字面值操作不同Python 3.x 现已不支持 <code class="docutils literal notranslate"><span class="pre">'ur'</span></code> 句法。</p>
<div class="versionadded">
<p><span class="versionmodified added">3.3 新版功能: </span>新增原始字节串 <code class="docutils literal notranslate"><span class="pre">'rb'</span></code> 前缀,是 <code class="docutils literal notranslate"><span class="pre">'br'</span></code> 的同义词。</p>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.3 新版功能: </span>支持 unicode 字面值(<code class="docutils literal notranslate"><span class="pre">u'value'</span></code>)遗留代码,简化 Python 2.x 和 3.x 并行代码库的维护工作。详见 <span class="target" id="index-40"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0414"><strong>PEP 414</strong></a></p>
</div>
<p id="index-21">前缀为 <code class="docutils literal notranslate"><span class="pre">'f'</span></code><code class="docutils literal notranslate"><span class="pre">'F'</span></code> 的字符串称为 <em class="dfn">格式字符串</em>;详见 <a class="reference internal" href="#f-strings"><span class="std std-ref">格式字符串字面值</span></a><code class="docutils literal notranslate"><span class="pre">'f'</span></code> 可与 <code class="docutils literal notranslate"><span class="pre">'r'</span></code> 连用,但不能与 <code class="docutils literal notranslate"><span class="pre">'b'</span></code><code class="docutils literal notranslate"><span class="pre">'u'</span></code> 连用,因此,可以使用原始格式字符串,但不能使用格式字节串字面值。</p>
<p>三引号字面值可以包含未转义的换行和引号(原样保留),除了连在一起的,用于终止字面值的,未经转义的三个引号。(&quot;引号&quot; 是启用字面值的字符,可以是 <code class="docutils literal notranslate"><span class="pre">'</span></code>,也可以是 <code class="docutils literal notranslate"><span class="pre">&quot;</span></code>。)</p>
<p id="index-22">如未标注 <code class="docutils literal notranslate"><span class="pre">'r'</span></code><code class="docutils literal notranslate"><span class="pre">'R'</span></code> 前缀,字符串和字节串字面值中,转义序列以类似 C 标准的规则进行解释。可用的转义序列如下:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 30%" />
<col style="width: 58%" />
<col style="width: 12%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>转义序列</p></th>
<th class="head"><p>含意</p></th>
<th class="head"><p>备注</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\newline</span></code></p></td>
<td><p>忽略反斜杠与换行符</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">\\</span></code></p></td>
<td><p>反斜杠(<code class="docutils literal notranslate"><span class="pre">\</span></code></p></td>
<td></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\'</span></code></p></td>
<td><p>单引号(<code class="docutils literal notranslate"><span class="pre">'</span></code></p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">\&quot;</span></code></p></td>
<td><p>双引号(<code class="docutils literal notranslate"><span class="pre">&quot;</span></code></p></td>
<td></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\a</span></code></p></td>
<td><p>ASCII 响铃BEL</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">\b</span></code></p></td>
<td><p>ASCII 退格符BS</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\f</span></code></p></td>
<td><p>ASCII 换页符FF</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">\n</span></code></p></td>
<td><p>ASCII 换行符LF</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\r</span></code></p></td>
<td><p>ASCII 回车符CR</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">\t</span></code></p></td>
<td><p>ASCII 水平制表符TAB</p></td>
<td></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\v</span></code></p></td>
<td><p>ASCII 垂直制表符VT</p></td>
<td></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">\ooo</span></code></p></td>
<td><p>八进制数 <em>ooo</em> 字符</p></td>
<td><p>(1,3)</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\xhh</span></code></p></td>
<td><p>十六进制数 <em>hh</em> 字符</p></td>
<td><p>(2,3)</p></td>
</tr>
</tbody>
</table>
<p>字符串字面值专用的转义序列:</p>
<table class="docutils align-default">
<colgroup>
<col style="width: 30%" />
<col style="width: 58%" />
<col style="width: 12%" />
</colgroup>
<thead>
<tr class="row-odd"><th class="head"><p>转义序列</p></th>
<th class="head"><p>含意</p></th>
<th class="head"><p>备注</p></th>
</tr>
</thead>
<tbody>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\N{name}</span></code></p></td>
<td><p>Unicode 数据库中名为 <em>name</em> 的字符</p></td>
<td><p>(4)</p></td>
</tr>
<tr class="row-odd"><td><p><code class="docutils literal notranslate"><span class="pre">\uxxxx</span></code></p></td>
<td><p>16 位十六进制数 <em>xxxx</em> 码位的字符</p></td>
<td><p>(5)</p></td>
</tr>
<tr class="row-even"><td><p><code class="docutils literal notranslate"><span class="pre">\Uxxxxxxxx</span></code></p></td>
<td><p>32 位 16 进制数 <em>xxxxxxxx</em> 码位的字符</p></td>
<td><p>(6)</p></td>
</tr>
</tbody>
</table>
<p>注释:</p>
<ol class="arabic">
<li><p>与 C 标准一致,接受最多三个八进制数字。</p></li>
<li><p>与 C 标准不同,必须为两个十六进制数字。</p></li>
<li><p><em>字节串</em> 字面值中,十六进制数和八进制数的转义码以相应数值代表每个字节。<em>字符串</em> 字面值中,这些转义码以相应数值代表每个 Unicode 字符。</p></li>
<li><div class="versionchanged">
<p><span class="versionmodified changed">在 3.3 版更改: </span>加入了对别名 <a class="footnote-reference brackets" href="#id13" id="id10">1</a> 的支持。</p>
</div>
</li>
<li><p>必须为 4 个十六进制数码。</p></li>
<li><p>表示任意 Unicode 字符。必须为 8 个十六进制数码。</p></li>
</ol>
<p id="index-23">与 C 标准不同,无法识别的转义序列在字符串里原样保留,即,<em>输出结果保留反斜杠</em>。(调试时,这种方式很有用:输错转义序列时,更容易在输出结果中识别错误。)注意,在字节串字面值内,字符串字面值专用的转义序列属于无法识别的转义序列。</p>
<blockquote>
<div><div class="versionchanged">
<p><span class="versionmodified changed">在 3.6 版更改: </span>无法识别的转义序列触发 <a class="reference internal" href="../library/exceptions.html#DeprecationWarning" title="DeprecationWarning"><code class="xref py py-exc docutils literal notranslate"><span class="pre">DeprecationWarning</span></code></a>。未来的 Python 发行版将改为触发 <a class="reference internal" href="../library/exceptions.html#SyntaxWarning" title="SyntaxWarning"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxWarning</span></code></a>,最终会改为触发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a></p>
</div>
</div></blockquote>
<p>即使在原始字面值中,引号也可以用反斜杠转义,但反斜杠会保留在输出结果里;例如 <code class="docutils literal notranslate"><span class="pre">r&quot;\&quot;&quot;</span></code> 是由两个字符组成的有效字符串字面值:反斜杠和双引号;<code class="docutils literal notranslate"><span class="pre">r&quot;\&quot;</span></code> 则不是有效字符串字面值(原始字符串也不能以奇数个反斜杠结尾)。尤其是,<em>原始字面值不能以单个反斜杠结尾</em> (反斜杠会转义其后的引号)。还要注意,反斜杠加换行在字面值中被解释为两个字符,而 <em>不是</em> 连续行。</p>
</section>
<section id="string-literal-concatenation">
<span id="string-concatenation"></span><h3><span class="section-number">2.4.2. </span>字符串字面值合并<a class="headerlink" href="#string-literal-concatenation" title="永久链接至标题"></a></h3>
<p>以空白符分隔的多个相邻字符串或字节串字面值,可用不同引号标注,等同于合并操作。因此,<code class="docutils literal notranslate"><span class="pre">&quot;hello&quot;</span> <span class="pre">'world'</span></code> 等价于 <code class="docutils literal notranslate"><span class="pre">&quot;helloworld&quot;</span></code>。此功能不需要反斜杠,即可将长字符串分为多个物理行,还可以为不同部分的字符串添加注释,例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">re</span><span class="o">.</span><span class="n">compile</span><span class="p">(</span><span class="s2">&quot;[A-Za-z_]&quot;</span> <span class="c1"># letter or underscore</span>
<span class="s2">&quot;[A-Za-z0-9_]*&quot;</span> <span class="c1"># letter, digit or underscore</span>
<span class="p">)</span>
</pre></div>
</div>
<p>注意,此功能在句法层面定义,在编译时实现。在运行时,合并字符串表达式必须使用 '+' 运算符。还要注意,字面值合并可以为每个部分应用不同的引号风格(甚至混用原始字符串和三引号字符串),格式字符串字面值也可以与纯字符串字面值合并。</p>
</section>
<section id="formatted-string-literals">
<span id="f-strings"></span><span id="index-24"></span><h3><span class="section-number">2.4.3. </span>格式字符串字面值<a class="headerlink" href="#formatted-string-literals" title="永久链接至标题"></a></h3>
<div class="versionadded">
<p><span class="versionmodified added">3.6 新版功能.</span></p>
</div>
<p><em class="dfn">格式字符串字面值</em> 或称 <em class="dfn">f-string</em> 是标注了 <code class="docutils literal notranslate"><span class="pre">'f'</span></code><code class="docutils literal notranslate"><span class="pre">'F'</span></code> 前缀的字符串字面值。这种字符串可包含替换字段,即以 <code class="docutils literal notranslate"><span class="pre">{}</span></code> 标注的表达式。其他字符串字面值只是常量,格式字符串字面值则是可在运行时求值的表达式。</p>
<p>除非字面值标记为原始字符串,否则,与在普通字符串字面值中一样,转义序列也会被解码。解码后,用于字符串内容的语法如下:</p>
<pre>
<strong id="grammar-token-f-string">f_string </strong> ::= (<a class="reference internal" href="#grammar-token-literal-char"><code class="xref docutils literal notranslate"><span class="pre">literal_char</span></code></a> | &quot;{{&quot; | &quot;}}&quot; | <a class="reference internal" href="#grammar-token-replacement-field"><code class="xref docutils literal notranslate"><span class="pre">replacement_field</span></code></a>)*
<strong id="grammar-token-replacement-field">replacement_field</strong> ::= &quot;{&quot; <a class="reference internal" href="#grammar-token-f-expression"><code class="xref docutils literal notranslate"><span class="pre">f_expression</span></code></a> [&quot;=&quot;] [&quot;!&quot; <a class="reference internal" href="#grammar-token-conversion"><code class="xref docutils literal notranslate"><span class="pre">conversion</span></code></a>] [&quot;:&quot; <a class="reference internal" href="#grammar-token-format-spec"><code class="xref docutils literal notranslate"><span class="pre">format_spec</span></code></a>] &quot;}&quot;
<strong id="grammar-token-f-expression">f_expression </strong> ::= (<a class="reference internal" href="expressions.html#grammar-token-conditional-expression"><code class="xref docutils literal notranslate"><span class="pre">conditional_expression</span></code></a> | &quot;*&quot; <a class="reference internal" href="expressions.html#grammar-token-or-expr"><code class="xref docutils literal notranslate"><span class="pre">or_expr</span></code></a>)
(&quot;,&quot; <a class="reference internal" href="expressions.html#grammar-token-conditional-expression"><code class="xref docutils literal notranslate"><span class="pre">conditional_expression</span></code></a> | &quot;,&quot; &quot;*&quot; <a class="reference internal" href="expressions.html#grammar-token-or-expr"><code class="xref docutils literal notranslate"><span class="pre">or_expr</span></code></a>)* [&quot;,&quot;]
| <a class="reference internal" href="expressions.html#grammar-token-yield-expression"><code class="xref docutils literal notranslate"><span class="pre">yield_expression</span></code></a>
<strong id="grammar-token-conversion">conversion </strong> ::= &quot;s&quot; | &quot;r&quot; | &quot;a&quot;
<strong id="grammar-token-format-spec">format_spec </strong> ::= (<a class="reference internal" href="#grammar-token-literal-char"><code class="xref docutils literal notranslate"><span class="pre">literal_char</span></code></a> | NULL | <a class="reference internal" href="#grammar-token-replacement-field"><code class="xref docutils literal notranslate"><span class="pre">replacement_field</span></code></a>)*
<strong id="grammar-token-literal-char">literal_char </strong> ::= &lt;any code point except &quot;{&quot;, &quot;}&quot; or NULL&gt;
</pre>
<p>双花括号 <code class="docutils literal notranslate"><span class="pre">'{{'</span></code><code class="docutils literal notranslate"><span class="pre">'}}'</span></code> 被替换为单花括号,花括号外的字符串仍按字面值处理。单左花括号 <code class="docutils literal notranslate"><span class="pre">'{'</span></code> 标记以 Python 表达式开头的替换字段。在表达式后加等于号 <code class="docutils literal notranslate"><span class="pre">'='</span></code>,可在求值后,同时显示表达式文本及其结果(用于调试)。 随后是用叹号 <code class="docutils literal notranslate"><span class="pre">'!'</span></code> 标记的转换字段。还可以在冒号 <code class="docutils literal notranslate"><span class="pre">':'</span></code> 后附加格式说明符。替换字段以右花括号 <code class="docutils literal notranslate"><span class="pre">'}'</span></code> 为结尾。</p>
<p>格式字符串字面值中,表达式的处理与圆括号中的常规 Python 表达式基本一样,但也有一些不同的地方。不允许使用空表达式;<a class="reference internal" href="expressions.html#lambda"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">lambda</span></code></a> 和赋值表达式 <code class="docutils literal notranslate"><span class="pre">:=</span></code> 必须显式用圆括号标注;替换表达式可以包含换行(例如,三引号字符串中),但不能包含注释;在格式字符串字面值语境内,按从左至右的顺序,为每个表达式求值。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.7 版更改: </span>Python 3.7 以前, 因为实现的问题,不允许在格式字符串字面值表达式中使用 <a class="reference internal" href="expressions.html#await"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">await</span></code></a> 表达式与包含 <a class="reference internal" href="compound_stmts.html#async-for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">async</span> <span class="pre">for</span></code></a> 子句的推导式。</p>
</div>
<p>表达式里含等号 <code class="docutils literal notranslate"><span class="pre">'='</span></code> 时,输出内容包括表达式文本、<code class="docutils literal notranslate"><span class="pre">'='</span></code> 、求值结果。输出内容可以保留表达式中左花括号 <code class="docutils literal notranslate"><span class="pre">'{'</span></code> 后,及 <code class="docutils literal notranslate"><span class="pre">'='</span></code> 后的空格。没有指定格式时,<code class="docutils literal notranslate"><span class="pre">'='</span></code> 默认调用表达式的 <a class="reference internal" href="../library/functions.html#repr" title="repr"><code class="xref py py-func docutils literal notranslate"><span class="pre">repr()</span></code></a>。指定了格式时,默认调用表达式的 <a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-func docutils literal notranslate"><span class="pre">str()</span></code></a>,除非声明了转换字段 <code class="docutils literal notranslate"><span class="pre">'!r'</span></code></p>
<div class="versionadded">
<p><span class="versionmodified added">3.8 新版功能: </span>等号 <code class="docutils literal notranslate"><span class="pre">'='</span></code></p>
</div>
<p>指定了转换符时,表达式求值的结果会先转换,再格式化。转换符 <code class="docutils literal notranslate"><span class="pre">'!s'</span></code> 调用 <a class="reference internal" href="../library/stdtypes.html#str" title="str"><code class="xref py py-func docutils literal notranslate"><span class="pre">str()</span></code></a> 转换求值结果,<code class="docutils literal notranslate"><span class="pre">'!r'</span></code> 调用 <a class="reference internal" href="../library/functions.html#repr" title="repr"><code class="xref py py-func docutils literal notranslate"><span class="pre">repr()</span></code></a><code class="docutils literal notranslate"><span class="pre">'!a'</span></code> 调用 <a class="reference internal" href="../library/functions.html#ascii" title="ascii"><code class="xref py py-func docutils literal notranslate"><span class="pre">ascii()</span></code></a></p>
<p>输出结果的格式化使用 <a class="reference internal" href="../library/functions.html#format" title="format"><code class="xref py py-func docutils literal notranslate"><span class="pre">format()</span></code></a> 协议。格式说明符传入表达式或转换结果的 <a class="reference internal" href="datamodel.html#object.__format__" title="object.__format__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__format__()</span></code></a> 方法。省略格式说明符,则传入空字符串。然后,格式化结果包含在整个字符串的最终值里。</p>
<p>顶层的格式说明符可以包含有嵌套的替换字段。这些嵌套字段也可以包含有自己的转换字段和 <a class="reference internal" href="../library/string.html#formatspec"><span class="std std-ref">格式说明符</span></a>,但不可再包含更深层嵌套的替换字段。这里的 <a class="reference internal" href="../library/string.html#formatspec"><span class="std std-ref">格式说明符微型语言</span></a> 与字符串 .format() 方法所使用的相同。</p>
<p>格式化字符串字面值可以拼接,但是一个替换字段不能拆分到多个字面值。</p>
<p>格式字符串字面值示例如下:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">name</span> <span class="o">=</span> <span class="s2">&quot;Fred&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;He said his name is </span><span class="si">{</span><span class="n">name</span><span class="si">!r}</span><span class="s2">.&quot;</span>
<span class="go">&quot;He said his name is &#39;Fred&#39;.&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;He said his name is </span><span class="si">{</span><span class="nb">repr</span><span class="p">(</span><span class="n">name</span><span class="p">)</span><span class="si">}</span><span class="s2">.&quot;</span> <span class="c1"># repr() is equivalent to !r</span>
<span class="go">&quot;He said his name is &#39;Fred&#39;.&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">width</span> <span class="o">=</span> <span class="mi">10</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">precision</span> <span class="o">=</span> <span class="mi">4</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">value</span> <span class="o">=</span> <span class="n">decimal</span><span class="o">.</span><span class="n">Decimal</span><span class="p">(</span><span class="s2">&quot;12.34567&quot;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;result: </span><span class="si">{</span><span class="n">value</span><span class="si">:{</span><span class="n">width</span><span class="si">}</span><span class="s2">.</span><span class="si">{</span><span class="n">precision</span><span class="si">}}</span><span class="s2">&quot;</span> <span class="c1"># nested fields</span>
<span class="go">&#39;result: 12.35&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">today</span> <span class="o">=</span> <span class="n">datetime</span><span class="p">(</span><span class="n">year</span><span class="o">=</span><span class="mi">2017</span><span class="p">,</span> <span class="n">month</span><span class="o">=</span><span class="mi">1</span><span class="p">,</span> <span class="n">day</span><span class="o">=</span><span class="mi">27</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">today</span><span class="si">:</span><span class="s2">%B %d, %Y</span><span class="si">}</span><span class="s2">&quot;</span> <span class="c1"># using date format specifier</span>
<span class="go">&#39;January 27, 2017&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">today</span><span class="si">=:</span><span class="s2">%B %d, %Y</span><span class="si">}</span><span class="s2">&quot;</span> <span class="c1"># using date format specifier and debugging</span>
<span class="go">&#39;today=January 27, 2017&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">number</span> <span class="o">=</span> <span class="mi">1024</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">number</span><span class="si">:</span><span class="s2">#0x</span><span class="si">}</span><span class="s2">&quot;</span> <span class="c1"># using integer format specifier</span>
<span class="go">&#39;0x400&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span> <span class="o">=</span> <span class="s2">&quot;bar&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="w"> </span><span class="n">foo</span><span class="w"> </span><span class="si">= }</span><span class="s2">&quot;</span> <span class="c1"># preserves whitespace</span>
<span class="go">&quot; foo = &#39;bar&#39;&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">line</span> <span class="o">=</span> <span class="s2">&quot;The mill&#39;s closed&quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">line</span><span class="w"> </span><span class="si">= }</span><span class="s2">&quot;</span>
<span class="go">&#39;line = &quot;The mill\&#39;s closed&quot;&#39;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">line</span><span class="w"> </span><span class="si">= :</span><span class="s2">20</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="go">&quot;line = The mill&#39;s closed &quot;</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;</span><span class="si">{</span><span class="n">line</span><span class="w"> </span><span class="si">= !r:</span><span class="s2">20</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="go">&#39;line = &quot;The mill\&#39;s closed&quot; &#39;</span>
</pre></div>
</div>
<p>与常规字符串字面值的语法一样,替换字段中的字符不能与外层格式字符串字面值的引号冲突:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="sa">f</span><span class="s2">&quot;abc </span><span class="si">{</span><span class="n">a</span><span class="p">[</span><span class="s2">&quot;x&quot;</span><span class="p">]</span><span class="si">}</span><span class="s2"> def&quot;</span> <span class="c1"># error: outer string literal ended prematurely</span>
<span class="sa">f</span><span class="s2">&quot;abc </span><span class="si">{</span><span class="n">a</span><span class="p">[</span><span class="s1">&#39;x&#39;</span><span class="p">]</span><span class="si">}</span><span class="s2"> def&quot;</span> <span class="c1"># workaround: use different quoting</span>
</pre></div>
</div>
<p>格式化表达式中不允许使用反斜杠,否则导致错误:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="sa">f</span><span class="s2">&quot;newline: </span><span class="si">{</span><span class="nb">ord</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span><span class="si">}</span><span class="s2">&quot;</span> <span class="c1"># raises SyntaxError</span>
</pre></div>
</div>
<p>如果要包含带反斜杠的值,请创建一个临时变量。</p>
<div class="doctest highlight-default notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="n">newline</span> <span class="o">=</span> <span class="nb">ord</span><span class="p">(</span><span class="s1">&#39;</span><span class="se">\n</span><span class="s1">&#39;</span><span class="p">)</span>
<span class="gp">&gt;&gt;&gt; </span><span class="sa">f</span><span class="s2">&quot;newline: </span><span class="si">{</span><span class="n">newline</span><span class="si">}</span><span class="s2">&quot;</span>
<span class="go">&#39;newline: 10&#39;</span>
</pre></div>
</div>
<p>即便未包含表达式,格式字符串字面值也不能用作文档字符串。</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">def</span> <span class="nf">foo</span><span class="p">():</span>
<span class="gp">... </span> <span class="sa">f</span><span class="s2">&quot;Not a docstring&quot;</span>
<span class="gp">...</span>
<span class="gp">&gt;&gt;&gt; </span><span class="n">foo</span><span class="o">.</span><span class="vm">__doc__</span> <span class="ow">is</span> <span class="kc">None</span>
<span class="go">True</span>
</pre></div>
</div>
<p>参阅 <span class="target" id="index-41"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0498"><strong>PEP 498</strong></a>,了解格式字符串字面值的提案,以及与格式字符串机制相关的 <a class="reference internal" href="../library/stdtypes.html#str.format" title="str.format"><code class="xref py py-meth docutils literal notranslate"><span class="pre">str.format()</span></code></a></p>
</section>
<section id="numeric-literals">
<span id="numbers"></span><h3><span class="section-number">2.4.4. </span>数值字面值<a class="headerlink" href="#numeric-literals" title="永久链接至标题"></a></h3>
<p id="index-26">数值字面值有三种类型:整数、浮点数、虚数。没有复数字面值(复数由实数加虚数构成)。</p>
<p>注意,数值字面值不含正负号;实际上,<code class="docutils literal notranslate"><span class="pre">-1</span></code> 等负数是由一元运算符 '<code class="docutils literal notranslate"><span class="pre">-</span></code>' 和字面值 <code class="docutils literal notranslate"><span class="pre">1</span></code> 合成的。</p>
</section>
<section id="integer-literals">
<span id="integers"></span><span id="index-27"></span><h3><span class="section-number">2.4.5. </span>整数字面值<a class="headerlink" href="#integer-literals" title="永久链接至标题"></a></h3>
<p>整数字面值词法定义如下:</p>
<pre>
<strong id="grammar-token-integer">integer </strong> ::= <a class="reference internal" href="#grammar-token-decinteger"><code class="xref docutils literal notranslate"><span class="pre">decinteger</span></code></a> | <a class="reference internal" href="#grammar-token-bininteger"><code class="xref docutils literal notranslate"><span class="pre">bininteger</span></code></a> | <a class="reference internal" href="#grammar-token-octinteger"><code class="xref docutils literal notranslate"><span class="pre">octinteger</span></code></a> | <a class="reference internal" href="#grammar-token-hexinteger"><code class="xref docutils literal notranslate"><span class="pre">hexinteger</span></code></a>
<strong id="grammar-token-decinteger">decinteger </strong> ::= <a class="reference internal" href="#grammar-token-nonzerodigit"><code class="xref docutils literal notranslate"><span class="pre">nonzerodigit</span></code></a> ([&quot;_&quot;] <a class="reference internal" href="#grammar-token-digit"><code class="xref docutils literal notranslate"><span class="pre">digit</span></code></a>)* | &quot;0&quot;+ ([&quot;_&quot;] &quot;0&quot;)*
<strong id="grammar-token-bininteger">bininteger </strong> ::= &quot;0&quot; (&quot;b&quot; | &quot;B&quot;) ([&quot;_&quot;] <a class="reference internal" href="#grammar-token-bindigit"><code class="xref docutils literal notranslate"><span class="pre">bindigit</span></code></a>)+
<strong id="grammar-token-octinteger">octinteger </strong> ::= &quot;0&quot; (&quot;o&quot; | &quot;O&quot;) ([&quot;_&quot;] <a class="reference internal" href="#grammar-token-octdigit"><code class="xref docutils literal notranslate"><span class="pre">octdigit</span></code></a>)+
<strong id="grammar-token-hexinteger">hexinteger </strong> ::= &quot;0&quot; (&quot;x&quot; | &quot;X&quot;) ([&quot;_&quot;] <a class="reference internal" href="#grammar-token-hexdigit"><code class="xref docutils literal notranslate"><span class="pre">hexdigit</span></code></a>)+
<strong id="grammar-token-nonzerodigit">nonzerodigit</strong> ::= &quot;1&quot;...&quot;9&quot;
<strong id="grammar-token-digit">digit </strong> ::= &quot;0&quot;...&quot;9&quot;
<strong id="grammar-token-bindigit">bindigit </strong> ::= &quot;0&quot; | &quot;1&quot;
<strong id="grammar-token-octdigit">octdigit </strong> ::= &quot;0&quot;...&quot;7&quot;
<strong id="grammar-token-hexdigit">hexdigit </strong> ::= <a class="reference internal" href="#grammar-token-digit"><code class="xref docutils literal notranslate"><span class="pre">digit</span></code></a> | &quot;a&quot;...&quot;f&quot; | &quot;A&quot;...&quot;F&quot;
</pre>
<p>整数字面值的长度没有限制,能一直大到占满可用内存。</p>
<p>确定数值时,会忽略字面值中的下划线。下划线只是为了分组数字,让数字更易读。下划线可在数字之间,也可在 <code class="docutils literal notranslate"><span class="pre">0x</span></code> 等基数说明符后。</p>
<p>注意,除了 0 以外,十进制数字的开头不允许有零。以免与 Python 3.0 版之前使用的 C 样式八进制字面值混淆。</p>
<p>整数字面值示例如下:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="mi">7</span> <span class="mi">2147483647</span> <span class="mo">0o177</span> <span class="mb">0b100110111</span>
<span class="mi">3</span> <span class="mi">79228162514264337593543950336</span> <span class="mo">0o377</span> <span class="mh">0xdeadbeef</span>
<span class="mi">100_000_000_000</span> <span class="mb">0b_1110_0101</span>
</pre></div>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.6 版更改: </span>现已支持在字面值中,用下划线分组数字。</p>
</div>
</section>
<section id="floating-point-literals">
<span id="floating"></span><span id="index-28"></span><h3><span class="section-number">2.4.6. </span>浮点数字面值<a class="headerlink" href="#floating-point-literals" title="永久链接至标题"></a></h3>
<p>浮点数字面值词法定义如下:</p>
<pre>
<strong id="grammar-token-floatnumber">floatnumber </strong> ::= <a class="reference internal" href="#grammar-token-pointfloat"><code class="xref docutils literal notranslate"><span class="pre">pointfloat</span></code></a> | <a class="reference internal" href="#grammar-token-exponentfloat"><code class="xref docutils literal notranslate"><span class="pre">exponentfloat</span></code></a>
<strong id="grammar-token-pointfloat">pointfloat </strong> ::= [<a class="reference internal" href="#grammar-token-digitpart"><code class="xref docutils literal notranslate"><span class="pre">digitpart</span></code></a>] <a class="reference internal" href="#grammar-token-fraction"><code class="xref docutils literal notranslate"><span class="pre">fraction</span></code></a> | <a class="reference internal" href="#grammar-token-digitpart"><code class="xref docutils literal notranslate"><span class="pre">digitpart</span></code></a> &quot;.&quot;
<strong id="grammar-token-exponentfloat">exponentfloat</strong> ::= (<a class="reference internal" href="#grammar-token-digitpart"><code class="xref docutils literal notranslate"><span class="pre">digitpart</span></code></a> | <a class="reference internal" href="#grammar-token-pointfloat"><code class="xref docutils literal notranslate"><span class="pre">pointfloat</span></code></a>) <a class="reference internal" href="#grammar-token-exponent"><code class="xref docutils literal notranslate"><span class="pre">exponent</span></code></a>
<strong id="grammar-token-digitpart">digitpart </strong> ::= <a class="reference internal" href="#grammar-token-digit"><code class="xref docutils literal notranslate"><span class="pre">digit</span></code></a> ([&quot;_&quot;] <a class="reference internal" href="#grammar-token-digit"><code class="xref docutils literal notranslate"><span class="pre">digit</span></code></a>)*
<strong id="grammar-token-fraction">fraction </strong> ::= &quot;.&quot; <a class="reference internal" href="#grammar-token-digitpart"><code class="xref docutils literal notranslate"><span class="pre">digitpart</span></code></a>
<strong id="grammar-token-exponent">exponent </strong> ::= (&quot;e&quot; | &quot;E&quot;) [&quot;+&quot; | &quot;-&quot;] <a class="reference internal" href="#grammar-token-digitpart"><code class="xref docutils literal notranslate"><span class="pre">digitpart</span></code></a>
</pre>
<p>注意,解析时,整数和指数部分总以 10 为基数。例如,<code class="docutils literal notranslate"><span class="pre">077e010</span></code> 是合法的,表示的数值与 <code class="docutils literal notranslate"><span class="pre">77e10</span></code> 相同。浮点数字面值的支持范围取决于具体实现。整数字面值支持用下划线分组数字。</p>
<p>浮点数字面值示例如下:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="mf">3.14</span> <span class="mf">10.</span> <span class="mf">.001</span> <span class="mf">1e100</span> <span class="mf">3.14e-10</span> <span class="mf">0e0</span> <span class="mf">3.14_15_93</span>
</pre></div>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.6 版更改: </span>现已支持在字面值中,用下划线分组数字。</p>
</div>
</section>
<section id="imaginary-literals">
<span id="imaginary"></span><span id="index-29"></span><h3><span class="section-number">2.4.7. </span>虚数字面值<a class="headerlink" href="#imaginary-literals" title="永久链接至标题"></a></h3>
<p>虚数字面值词法定义如下:</p>
<pre>
<strong id="grammar-token-imagnumber">imagnumber</strong> ::= (<a class="reference internal" href="#grammar-token-floatnumber"><code class="xref docutils literal notranslate"><span class="pre">floatnumber</span></code></a> | <a class="reference internal" href="#grammar-token-digitpart"><code class="xref docutils literal notranslate"><span class="pre">digitpart</span></code></a>) (&quot;j&quot; | &quot;J&quot;)
</pre>
<p>虚数字面值生成实部为 0.0 的复数。复数由一对浮点数表示,它们的取值范围相同。创建实部不为零的复数,则需添加浮点数,例如 <code class="docutils literal notranslate"><span class="pre">(3+4j)</span></code>。虚数字面值示例如下:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="mf">3.14</span><span class="n">j</span> <span class="mf">10.</span><span class="n">j</span> <span class="mi">10</span><span class="n">j</span> <span class="mf">.001</span><span class="n">j</span> <span class="mf">1e100j</span> <span class="mf">3.14e-10</span><span class="n">j</span> <span class="mf">3.14_15_93</span><span class="n">j</span>
</pre></div>
</div>
</section>
</section>
<section id="operators">
<span id="id11"></span><h2><span class="section-number">2.5. </span>运算符<a class="headerlink" href="#operators" title="永久链接至标题"></a></h2>
<p id="index-30">运算符如下所示:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>+ - * ** / // % @
&lt;&lt; &gt;&gt; &amp; | ^ ~ :=
&lt; &gt; &lt;= &gt;= == !=
</pre></div>
</div>
</section>
<section id="delimiters">
<span id="id12"></span><h2><span class="section-number">2.6. </span>分隔符<a class="headerlink" href="#delimiters" title="永久链接至标题"></a></h2>
<p id="index-31">以下形符在语法中为分隔符:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>( ) [ ] { }
, : . ; @ = -&gt;
+= -= *= /= //= %= @=
&amp;= |= ^= &gt;&gt;= &lt;&lt;= **=
</pre></div>
</div>
<p>句点也可以用于浮点数和虚数字面值。三个连续句点表示省略符。列表后半部分是增强赋值操作符,用作词法分隔符,但也可以执行运算。</p>
<p>以下 ASCII 字符具有特殊含义,对词法分析器有重要意义:</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>&#39; &quot; # \
</pre></div>
</div>
<p>以下 ASCII 字符不用于 Python。在字符串字面值或注释外使用时将直接报错</p>
<div class="highlight-none notranslate"><div class="highlight"><pre><span></span>$ ? `
</pre></div>
</div>
<p class="rubric">备注</p>
<dl class="footnote brackets">
<dt class="label" id="id13"><span class="brackets"><a class="fn-backref" href="#id10">1</a></span></dt>
<dd><p><a class="reference external" href="http://www.unicode.org/Public/11.0.0/ucd/NameAliases.txt">http://www.unicode.org/Public/11.0.0/ucd/NameAliases.txt</a></p>
</dd>
</dl>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">2. 词法分析</a><ul>
<li><a class="reference internal" href="#line-structure">2.1. 行结构</a><ul>
<li><a class="reference internal" href="#logical-lines">2.1.1. 逻辑行</a></li>
<li><a class="reference internal" href="#physical-lines">2.1.2. 物理行</a></li>
<li><a class="reference internal" href="#comments">2.1.3. 注释</a></li>
<li><a class="reference internal" href="#encoding-declarations">2.1.4. 编码声明</a></li>
<li><a class="reference internal" href="#explicit-line-joining">2.1.5. 显式拼接行</a></li>
<li><a class="reference internal" href="#implicit-line-joining">2.1.6. 隐式拼接行</a></li>
<li><a class="reference internal" href="#blank-lines">2.1.7. 空白行</a></li>
<li><a class="reference internal" href="#indentation">2.1.8. 缩进</a></li>
<li><a class="reference internal" href="#whitespace-between-tokens">2.1.9. 形符间的空白字符</a></li>
</ul>
</li>
<li><a class="reference internal" href="#other-tokens">2.2. 其他形符</a></li>
<li><a class="reference internal" href="#identifiers">2.3. 标识符和关键字</a><ul>
<li><a class="reference internal" href="#keywords">2.3.1. 关键字</a></li>
<li><a class="reference internal" href="#reserved-classes-of-identifiers">2.3.2. 保留的标识符类</a></li>
</ul>
</li>
<li><a class="reference internal" href="#literals">2.4. 字面值</a><ul>
<li><a class="reference internal" href="#string-and-bytes-literals">2.4.1. 字符串与字节串字面值</a></li>
<li><a class="reference internal" href="#string-literal-concatenation">2.4.2. 字符串字面值合并</a></li>
<li><a class="reference internal" href="#formatted-string-literals">2.4.3. 格式字符串字面值</a></li>
<li><a class="reference internal" href="#numeric-literals">2.4.4. 数值字面值</a></li>
<li><a class="reference internal" href="#integer-literals">2.4.5. 整数字面值</a></li>
<li><a class="reference internal" href="#floating-point-literals">2.4.6. 浮点数字面值</a></li>
<li><a class="reference internal" href="#imaginary-literals">2.4.7. 虚数字面值</a></li>
</ul>
</li>
<li><a class="reference internal" href="#operators">2.5. 运算符</a></li>
<li><a class="reference internal" href="#delimiters">2.6. 分隔符</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="introduction.html"
title="上一章"><span class="section-number">1. </span>概述</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="datamodel.html"
title="下一章"><span class="section-number">3. </span>数据模型</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/lexical_analysis.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="datamodel.html" title="3. 数据模型"
>下一页</a> |</li>
<li class="right" >
<a href="introduction.html" title="1. 概述"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>

View File

@@ -0,0 +1,723 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>7. 简单语句 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="8. 复合语句" href="compound_stmts.html" />
<link rel="prev" title="6. 表达式" href="expressions.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/simple_stmts.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">7. 简单语句</a><ul>
<li><a class="reference internal" href="#expression-statements">7.1. 表达式语句</a></li>
<li><a class="reference internal" href="#assignment-statements">7.2. 赋值语句</a><ul>
<li><a class="reference internal" href="#augmented-assignment-statements">7.2.1. 增强赋值语句</a></li>
<li><a class="reference internal" href="#annotated-assignment-statements">7.2.2. 带标注的赋值语句</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-assert-statement">7.3. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">assert</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-pass-statement">7.4. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">pass</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-del-statement">7.5. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">del</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-return-statement">7.6. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-yield-statement">7.7. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-raise-statement">7.8. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-break-statement">7.9. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-continue-statement">7.10. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-import-statement">7.11. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code> 语句</a><ul>
<li><a class="reference internal" href="#future-statements">7.11.1. future 语句</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-global-statement">7.12. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-nonlocal-statement">7.13. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code> 语句</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="expressions.html"
title="上一章"><span class="section-number">6. </span>表达式</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="compound_stmts.html"
title="下一章"><span class="section-number">8. </span>复合语句</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/simple_stmts.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/simple_stmts.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="compound_stmts.html" title="8. 复合语句"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="expressions.html" title="6. 表达式"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="simple-statements">
<span id="simple"></span><h1><span class="section-number">7. </span>简单语句<a class="headerlink" href="#simple-statements" title="永久链接至标题"></a></h1>
<p id="index-0">简单语句由一个单独的逻辑行构成。 多条简单语句可以存在于同一行内并以分号分隔。 简单语句的句法为:</p>
<pre>
<strong id="grammar-token-simple-stmt">simple_stmt</strong> ::= <a class="reference internal" href="#grammar-token-expression-stmt"><code class="xref docutils literal notranslate"><span class="pre">expression_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-assert-stmt"><code class="xref docutils literal notranslate"><span class="pre">assert_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-assignment-stmt"><code class="xref docutils literal notranslate"><span class="pre">assignment_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-augmented-assignment-stmt"><code class="xref docutils literal notranslate"><span class="pre">augmented_assignment_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-annotated-assignment-stmt"><code class="xref docutils literal notranslate"><span class="pre">annotated_assignment_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-pass-stmt"><code class="xref docutils literal notranslate"><span class="pre">pass_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-del-stmt"><code class="xref docutils literal notranslate"><span class="pre">del_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-return-stmt"><code class="xref docutils literal notranslate"><span class="pre">return_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-yield-stmt"><code class="xref docutils literal notranslate"><span class="pre">yield_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-raise-stmt"><code class="xref docutils literal notranslate"><span class="pre">raise_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-break-stmt"><code class="xref docutils literal notranslate"><span class="pre">break_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-continue-stmt"><code class="xref docutils literal notranslate"><span class="pre">continue_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-import-stmt"><code class="xref docutils literal notranslate"><span class="pre">import_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-future-stmt"><code class="xref docutils literal notranslate"><span class="pre">future_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-global-stmt"><code class="xref docutils literal notranslate"><span class="pre">global_stmt</span></code></a>
| <a class="reference internal" href="#grammar-token-nonlocal-stmt"><code class="xref docutils literal notranslate"><span class="pre">nonlocal_stmt</span></code></a>
</pre>
<section id="expression-statements">
<span id="exprstmts"></span><h2><span class="section-number">7.1. </span>表达式语句<a class="headerlink" href="#expression-statements" title="永久链接至标题"></a></h2>
<span class="target" id="index-1"></span><p id="index-2">表达式语句用于计算和写入值(大多是在交互模式下),或者(通常情况)调用一个过程 (过程就是不返回有意义结果的函数;在 Python 中,过程的返回值为 <code class="docutils literal notranslate"><span class="pre">None</span></code>)。 表达式语句的其他使用方式也是允许且有特定用处的。 表达式语句的句法为:</p>
<pre>
<strong id="grammar-token-expression-stmt">expression_stmt</strong> ::= <a class="reference internal" href="expressions.html#grammar-token-starred-expression"><code class="xref docutils literal notranslate"><span class="pre">starred_expression</span></code></a>
</pre>
<p>表达式语句会对指定的表达式列表(也可能为单一表达式)进行求值。</p>
<p id="index-3">在交互模式下,如果结果值不为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,它会通过内置的 <a class="reference internal" href="../library/functions.html#repr" title="repr"><code class="xref py py-func docutils literal notranslate"><span class="pre">repr()</span></code></a> 函数转换为一个字符串,该结果字符串将以单独一行的形式写入标准输出(例外情况是如果结果为 <code class="docutils literal notranslate"><span class="pre">None</span></code>,则该过程调用不产生任何输出。)</p>
</section>
<section id="assignment-statements">
<span id="assignment"></span><h2><span class="section-number">7.2. </span>赋值语句<a class="headerlink" href="#assignment-statements" title="永久链接至标题"></a></h2>
<p id="index-4">赋值语句用于将名称(重)绑定到特定值,以及修改属性或可变对象的成员项:</p>
<pre>
<strong id="grammar-token-assignment-stmt">assignment_stmt</strong> ::= (<a class="reference internal" href="#grammar-token-target-list"><code class="xref docutils literal notranslate"><span class="pre">target_list</span></code></a> &quot;=&quot;)+ (<a class="reference internal" href="expressions.html#grammar-token-starred-expression"><code class="xref docutils literal notranslate"><span class="pre">starred_expression</span></code></a> | <a class="reference internal" href="expressions.html#grammar-token-yield-expression"><code class="xref docutils literal notranslate"><span class="pre">yield_expression</span></code></a>)
<strong id="grammar-token-target-list">target_list </strong> ::= <a class="reference internal" href="#grammar-token-target"><code class="xref docutils literal notranslate"><span class="pre">target</span></code></a> (&quot;,&quot; <a class="reference internal" href="#grammar-token-target"><code class="xref docutils literal notranslate"><span class="pre">target</span></code></a>)* [&quot;,&quot;]
<strong id="grammar-token-target">target </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>
| &quot;(&quot; [<a class="reference internal" href="#grammar-token-target-list"><code class="xref docutils literal notranslate"><span class="pre">target_list</span></code></a>] &quot;)&quot;
| &quot;[&quot; [<a class="reference internal" href="#grammar-token-target-list"><code class="xref docutils literal notranslate"><span class="pre">target_list</span></code></a>] &quot;]&quot;
| <a class="reference internal" href="expressions.html#grammar-token-attributeref"><code class="xref docutils literal notranslate"><span class="pre">attributeref</span></code></a>
| <a class="reference internal" href="expressions.html#grammar-token-subscription"><code class="xref docutils literal notranslate"><span class="pre">subscription</span></code></a>
| <a class="reference internal" href="expressions.html#grammar-token-slicing"><code class="xref docutils literal notranslate"><span class="pre">slicing</span></code></a>
| &quot;*&quot; <a class="reference internal" href="#grammar-token-target"><code class="xref docutils literal notranslate"><span class="pre">target</span></code></a>
</pre>
<p>(请参阅 <a class="reference internal" href="expressions.html#primaries"><span class="std std-ref">原型</span></a> 一节了解 <em>属性引用</em>, <em>抽取</em><em>切片</em> 的句法定义。)</p>
<p>赋值语句会对指定的表达式列表进行求值(注意这可能为单一表达式或是由逗号分隔的列表,后者将产生一个元组)并将单一结果对象从左至右逐个赋值给目标列表。</p>
<p id="index-5">赋值是根据目标(列表)的格式递归地定义的。 当目标为一个可变对象(属性引用、抽取或切片)的组成部分时,该可变对象必须最终执行赋值并决定其有效性,如果赋值操作不可接受也可能引发异常。 各种类型可用的规则和引发的异常通过对象类型的定义给出(参见 <a class="reference internal" href="datamodel.html#types"><span class="std std-ref">标准类型层级结构</span></a> 一节)。</p>
<p id="index-6">对象赋值的目标对象可以包含于圆括号或方括号内,具体操作按以下方式递归地定义。</p>
<ul class="simple">
<li><p>如果目标列表为后面不带逗号、可以包含于圆括号内的单一目标,则将对象赋值给该目标。</p></li>
<li><p>否则:该对象必须为具有与目标列表相同项数的可迭代对象,这些项将按从左至右的顺序被赋值给对应的目标。</p>
<ul>
<li><p>如果目标列表包含一个带有星号前缀的目标,这称为“加星”目标:则该对象至少必须为与目标列表项数减一相同项数的可迭代对象。 该可迭代对象前面的项将按从左至右的顺序被赋值给加星目标之前的目标。 该可迭代对象末尾的项将被赋值给加星目标之后的目标。 然后该可迭代对象中剩余项的列表将被赋值给加星目标(该列表可以为空)。</p></li>
<li><p>否则:该对象必须为具有与目标列表相同项数的可迭代对象,这些项将按从左至右的顺序被赋值给对应的目标。</p></li>
</ul>
</li>
</ul>
<p>对象赋值给单个目标的操作按以下方式递归地定义。</p>
<ul>
<li><p>如果目标为标识符(名称):</p>
<ul class="simple">
<li><p>如果该名称未出现于当前代码块的 <a class="reference internal" href="#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a><a class="reference internal" href="#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> 语句中:该名称将被绑定到当前局部命名空间的对象。</p></li>
<li><p>否则:该名称将被分别绑定到全局命名空间或由 <a class="reference internal" href="#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> 所确定的外层命名空间的对象。</p></li>
</ul>
<p id="index-7">如果该名称已经被绑定则将被重新绑定。 这可能导致之前被绑定到该名称的对象的引用计数变为零,造成该对象进入释放过程并调用其析构器(如果存在)。</p>
</li>
<li id="index-8"><p>如果该对象为属性引用:引用中的原型表达式会被求值。 它应该产生一个具有可赋值属性的对象;否则将引发 <a class="reference internal" href="../library/exceptions.html#TypeError" title="TypeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">TypeError</span></code></a>。 该对象会被要求将可赋值对象赋值给指定的属性;如果它无法执行赋值,则会引发异常 (通常应为 <a class="reference internal" href="../library/exceptions.html#AttributeError" title="AttributeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AttributeError</span></code></a> 但并不强制要求)。</p>
<p id="attr-target-note">注意:如果该对象为类实例并且属性引用在赋值运算符的两侧都出现,则右侧表达式 <code class="docutils literal notranslate"><span class="pre">a.x</span></code> 可以访问实例属性或(如果实例属性不存在)类属性。 左侧目标 <code class="docutils literal notranslate"><span class="pre">a.x</span></code> 将总是设定为实例属性,并在必要时创建该实例属性。 因此 <code class="docutils literal notranslate"><span class="pre">a.x</span></code> 的两次出现不一定指向相同的属性:如果右侧表达式指向一个类属性,则左侧会创建一个新的实例属性作为赋值的目标:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">class</span> <span class="nc">Cls</span><span class="p">:</span>
<span class="n">x</span> <span class="o">=</span> <span class="mi">3</span> <span class="c1"># class variable</span>
<span class="n">inst</span> <span class="o">=</span> <span class="n">Cls</span><span class="p">()</span>
<span class="n">inst</span><span class="o">.</span><span class="n">x</span> <span class="o">=</span> <span class="n">inst</span><span class="o">.</span><span class="n">x</span> <span class="o">+</span> <span class="mi">1</span> <span class="c1"># writes inst.x as 4 leaving Cls.x as 3</span>
</pre></div>
</div>
<p>此描述不一定作用于描述器属性,例如通过 <a class="reference internal" href="../library/functions.html#property" title="property"><code class="xref py py-func docutils literal notranslate"><span class="pre">property()</span></code></a> 创建的特征属性。</p>
</li>
<li id="index-9"><p>如果目标为一个抽取项:引用中的原型表达式会被求值。 它应当产生一个可变序列对象(例如列表)或一个映射对象(例如字典)。 接下来,该抽取表达式会被求值。</p>
<p id="index-10">如果原型为一个可变序列对象(例如列表),抽取应产生一个整数。 如其为负值,则再加上序列长度。 结果值必须为一个小于序列长度的非负整数,序列将把被赋值对象赋值给该整数指定索引号的项。 如果索引超出范围,将会引发 <a class="reference internal" href="../library/exceptions.html#IndexError" title="IndexError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">IndexError</span></code></a> (给被抽取序列赋值不能向列表添加新项)。</p>
<p id="index-11">如果原型为一个映射对象(例如字典),抽取必须具有与该映射的键类型相兼容的类型,然后映射中会创建一个将抽取映射到被赋值对象的键/值对。 这可以是替换一个现有键/值对并保持相同键值,也可以是插入一个新键/值对(如果具有相同值的键不存在)。</p>
<p>对于用户定义对象,会调用 <a class="reference internal" href="datamodel.html#object.__setitem__" title="object.__setitem__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__setitem__()</span></code></a> 方法并附带适当的参数。</p>
</li>
<li id="index-12"><p>如果目标为一个切片:引用中的原型表达式会被求值。 它应当产生一个可变序列对象(例如列表)。 被赋值对象应当是一个相同类型的序列对象。 接下来,下界与上界表达式如果存在的话将被求值;默认值分别为零和序列长度。 上下边界值应当为整数。 如果某一边界为负值,则会加上序列长度。 求出的边界会被裁剪至介于零和序列长度的开区间中。 最后,将要求序列对象以被赋值序列的项替换该切片。 切片的长度可能与被赋值序列的长度不同,这会在目标序列允许的情况下改变目标序列的长度。</p></li>
</ul>
<div class="impl-detail compound">
<p><strong>CPython implementation detail:</strong> 在当前实现中,目标的句法被当作与表达式的句法相同,无效的句法会在代码生成阶段被拒绝,导致不太详细的错误信息。</p>
</div>
<p>虽然赋值的定义意味着左手边与右手边的重叠是“同时”进行的(例如 <code class="docutils literal notranslate"><span class="pre">a,</span> <span class="pre">b</span> <span class="pre">=</span> <span class="pre">b,</span> <span class="pre">a</span></code> 会交换两个变量的值),但在赋值给变量的多项集 <em>之内</em> 的重叠是从左至右进行的,这有时会令人混淆。 例如,以下程序将会打印出 <code class="docutils literal notranslate"><span class="pre">[0,</span> <span class="pre">2]</span></code>:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="n">x</span> <span class="o">=</span> <span class="p">[</span><span class="mi">0</span><span class="p">,</span> <span class="mi">1</span><span class="p">]</span>
<span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="n">i</span><span class="p">,</span> <span class="n">x</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">2</span> <span class="c1"># i is updated, then x[i] is updated</span>
<span class="nb">print</span><span class="p">(</span><span class="n">x</span><span class="p">)</span>
</pre></div>
</div>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-53"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3132"><strong>PEP 3132</strong></a> - 扩展的可迭代对象拆包</dt><dd><p><code class="docutils literal notranslate"><span class="pre">*target</span></code> 特性的规范说明。</p>
</dd>
</dl>
</div>
<section id="augmented-assignment-statements">
<span id="augassign"></span><h3><span class="section-number">7.2.1. </span>增强赋值语句<a class="headerlink" href="#augmented-assignment-statements" title="永久链接至标题"></a></h3>
<p id="index-14">增强赋值语句就是在单个语句中将二元运算和赋值语句合为一体:</p>
<pre>
<strong id="grammar-token-augmented-assignment-stmt">augmented_assignment_stmt</strong> ::= <a class="reference internal" href="#grammar-token-augtarget"><code class="xref docutils literal notranslate"><span class="pre">augtarget</span></code></a> <a class="reference internal" href="#grammar-token-augop"><code class="xref docutils literal notranslate"><span class="pre">augop</span></code></a> (<a class="reference internal" href="expressions.html#grammar-token-expression-list"><code class="xref docutils literal notranslate"><span class="pre">expression_list</span></code></a> | <a class="reference internal" href="expressions.html#grammar-token-yield-expression"><code class="xref docutils literal notranslate"><span class="pre">yield_expression</span></code></a>)
<strong id="grammar-token-augtarget">augtarget </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> | <a class="reference internal" href="expressions.html#grammar-token-attributeref"><code class="xref docutils literal notranslate"><span class="pre">attributeref</span></code></a> | <a class="reference internal" href="expressions.html#grammar-token-subscription"><code class="xref docutils literal notranslate"><span class="pre">subscription</span></code></a> | <a class="reference internal" href="expressions.html#grammar-token-slicing"><code class="xref docutils literal notranslate"><span class="pre">slicing</span></code></a>
<strong id="grammar-token-augop">augop </strong> ::= &quot;+=&quot; | &quot;-=&quot; | &quot;*=&quot; | &quot;&#64;=&quot; | &quot;/=&quot; | &quot;//=&quot; | &quot;%=&quot; | &quot;**=&quot;
| &quot;&gt;&gt;=&quot; | &quot;&lt;&lt;=&quot; | &quot;&amp;=&quot; | &quot;^=&quot; | &quot;|=&quot;
</pre>
<p>(请参阅 <a class="reference internal" href="expressions.html#primaries"><span class="std std-ref">原型</span></a> 一节了解最后三种符号的句法定义。)</p>
<p>增强赋值语句将对目标和表达式列表求值(与普通赋值语句不同的是,前者不能为可迭代对象拆包),对两个操作数相应类型的赋值执行指定的二元运算,并将结果赋值给原始目标。 目标仅会被求值一次。</p>
<p>增强赋值语句例如 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">+=</span> <span class="pre">1</span></code> 可以改写为 <code class="docutils literal notranslate"><span class="pre">x</span> <span class="pre">=</span> <span class="pre">x</span> <span class="pre">+</span> <span class="pre">1</span></code> 获得类似但并非完全等价的效果。 在增强赋值的版本中,<code class="docutils literal notranslate"><span class="pre">x</span></code> 仅会被求值一次。 而且,在可能的情况下,实际的运算是 <em>原地</em> 执行的,也就是说并不是创建一个新对象并将其赋值给目标,而是直接修改原对象。</p>
<p>不同于普通赋值,增强赋值会在对右手边求值 <em>之前</em> 对左手边求值。 例如,<code class="docutils literal notranslate"><span class="pre">a[i]</span> <span class="pre">+=</span> <span class="pre">f(x)</span></code> 首先查找 <code class="docutils literal notranslate"><span class="pre">a[i]</span></code>,然后对 <code class="docutils literal notranslate"><span class="pre">f(x)</span></code> 求值并执行加法操作,最后将结果写回到 <code class="docutils literal notranslate"><span class="pre">a[i]</span></code></p>
<p>除了在单个语句中赋值给元组和多个目标的例外情况,增强赋值语句的赋值操作处理方式与普通赋值相同。 类似地,除了可能存在 <em>原地</em> 操作行为的例外情况,增强赋值语句执行的二元运算也与普通二元运算相同。</p>
<p>对于属性引用类目标,针对常规赋值的 <a class="reference internal" href="#attr-target-note"><span class="std std-ref">关于类和实例属性的警告</span></a> 也同样适用。</p>
</section>
<section id="annotated-assignment-statements">
<span id="annassign"></span><h3><span class="section-number">7.2.2. </span>带标注的赋值语句<a class="headerlink" href="#annotated-assignment-statements" title="永久链接至标题"></a></h3>
<p id="index-15"><a class="reference internal" href="../glossary.html#term-variable-annotation"><span class="xref std std-term">标注</span></a> 赋值就是在单个语句中将变量或属性标注和可选的赋值语句合为一体:</p>
<pre>
<strong id="grammar-token-annotated-assignment-stmt">annotated_assignment_stmt</strong> ::= <a class="reference internal" href="#grammar-token-augtarget"><code class="xref docutils literal notranslate"><span class="pre">augtarget</span></code></a> &quot;:&quot; <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>
[&quot;=&quot; (<a class="reference internal" href="expressions.html#grammar-token-starred-expression"><code class="xref docutils literal notranslate"><span class="pre">starred_expression</span></code></a> | <a class="reference internal" href="expressions.html#grammar-token-yield-expression"><code class="xref docutils literal notranslate"><span class="pre">yield_expression</span></code></a>)]
</pre>
<p>与普通 <a class="reference internal" href="#assignment"><span class="std std-ref">赋值语句</span></a> 的差别在于仅允许单个目标。</p>
<p>对于将简单名称作为赋值目标的情况,如果是在类或模块作用域中,标注会被求值并存入一个特殊的类或模块属性 <code class="xref py py-attr docutils literal notranslate"><span class="pre">__annotations__</span></code> 中,这是一个将变量名称(如为私有会被移除)映射到被求值标注的字典。 此属性为可写并且在类或模块体开始执行时如果静态地发现标注就会自动创建。</p>
<p>对于将表达式作为赋值目标的情况,如果是在类或模块作用域中,标注会被求值,但不会保存。</p>
<p>如果一个名称在函数作用域内被标注,则该名称为该作用域的局部变量。 标注绝不会在函数作用域内被求值和保存。</p>
<p>如果存在右手边,带标注的赋值会在对标注求值之前(如果适用)执行实际的赋值。 如果用作表达式目标的右手边不存在,则解释器会对目标求值,但最后的 <a class="reference internal" href="datamodel.html#object.__setitem__" title="object.__setitem__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__setitem__()</span></code></a><a class="reference internal" href="datamodel.html#object.__setattr__" title="object.__setattr__"><code class="xref py py-meth docutils literal notranslate"><span class="pre">__setattr__()</span></code></a> 调用除外。</p>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-54"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0526"><strong>PEP 526</strong></a> - 变量标注的语法</dt><dd><p>该提议增加了标注变量(也包括类变量和实例变量)类型的语法,而不再是通过注释来进行表达。</p>
</dd>
<dt><span class="target" id="index-55"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0484"><strong>PEP 484</strong></a> - 类型提示</dt><dd><p>该提议增加了 <a class="reference internal" href="../library/typing.html#module-typing" title="typing: Support for type hints (see :pep:`484`)."><code class="xref py py-mod docutils literal notranslate"><span class="pre">typing</span></code></a> 模块以便为类型标注提供标准句法,可被静态分析工具和 IDE 所使用。</p>
</dd>
</dl>
</div>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.8 版更改: </span>现在带有标注的赋值允许在右边以同样的表达式作为常规赋值。 之前,某些表达式(例如未加圆括号的元组表达式)会导致语法错误。</p>
</div>
</section>
</section>
<section id="the-assert-statement">
<span id="assert"></span><h2><span class="section-number">7.3. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">assert</span></code> 语句<a class="headerlink" href="#the-assert-statement" title="永久链接至标题"></a></h2>
<p id="index-18">assert 语句是在程序中插入调试性断言的简便方式:</p>
<pre>
<strong id="grammar-token-assert-stmt">assert_stmt</strong> ::= &quot;assert&quot; <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> [&quot;,&quot; <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>]
</pre>
<p>简单形式 <code class="docutils literal notranslate"><span class="pre">assert</span> <span class="pre">expression</span></code> 等价于</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">__debug__</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">expression</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">AssertionError</span>
</pre></div>
</div>
<p>扩展形式 <code class="docutils literal notranslate"><span class="pre">assert</span> <span class="pre">expression1,</span> <span class="pre">expression2</span></code> 等价于</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">if</span> <span class="n">__debug__</span><span class="p">:</span>
<span class="k">if</span> <span class="ow">not</span> <span class="n">expression1</span><span class="p">:</span> <span class="k">raise</span> <span class="ne">AssertionError</span><span class="p">(</span><span class="n">expression2</span><span class="p">)</span>
</pre></div>
</div>
<p id="index-19">以上等价形式假定 <a class="reference internal" href="../library/constants.html#__debug__" title="__debug__"><code class="xref py py-const docutils literal notranslate"><span class="pre">__debug__</span></code></a><a class="reference internal" href="../library/exceptions.html#AssertionError" title="AssertionError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">AssertionError</span></code></a> 指向具有指定名称的内置变量。 在当前实现中,内置变量 <a class="reference internal" href="../library/constants.html#__debug__" title="__debug__"><code class="xref py py-const docutils literal notranslate"><span class="pre">__debug__</span></code></a> 在正常情况下为 <code class="docutils literal notranslate"><span class="pre">True</span></code>,在请求优化时为 <code class="docutils literal notranslate"><span class="pre">False</span></code> (对应命令行选项为 <a class="reference internal" href="../using/cmdline.html#cmdoption-o"><code class="xref std std-option docutils literal notranslate"><span class="pre">-O</span></code></a>)。 如果在编译时请求优化,当前代码生成器不会为 assert 语句发出任何代码。 请注意不必在错误信息中包含失败表达式的源代码;它会被作为栈追踪的一部分被显示。</p>
<p>赋值给 <a class="reference internal" href="../library/constants.html#__debug__" title="__debug__"><code class="xref py py-const docutils literal notranslate"><span class="pre">__debug__</span></code></a> 是非法的。 该内置变量的值会在解释器启动时确定。</p>
</section>
<section id="the-pass-statement">
<span id="pass"></span><h2><span class="section-number">7.4. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">pass</span></code> 语句<a class="headerlink" href="#the-pass-statement" title="永久链接至标题"></a></h2>
<pre id="index-20">
<strong id="grammar-token-pass-stmt">pass_stmt</strong> ::= &quot;pass&quot;
</pre>
<p><a class="reference internal" href="#pass"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">pass</span></code></a> 是一个空操作 --- 当它被执行时,什么都不发生。 它适合当语法上需要一条语句但并不需要执行任何代码时用来临时占位,例如:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">def</span> <span class="nf">f</span><span class="p">(</span><span class="n">arg</span><span class="p">):</span> <span class="k">pass</span> <span class="c1"># a function that does nothing (yet)</span>
<span class="k">class</span> <span class="nc">C</span><span class="p">:</span> <span class="k">pass</span> <span class="c1"># a class with no methods (yet)</span>
</pre></div>
</div>
</section>
<section id="the-del-statement">
<span id="del"></span><h2><span class="section-number">7.5. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">del</span></code> 语句<a class="headerlink" href="#the-del-statement" title="永久链接至标题"></a></h2>
<pre id="index-21">
<strong id="grammar-token-del-stmt">del_stmt</strong> ::= &quot;del&quot; <a class="reference internal" href="#grammar-token-target-list"><code class="xref docutils literal notranslate"><span class="pre">target_list</span></code></a>
</pre>
<p>删除是递归定义的,与赋值的定义方式非常类似。 此处不再详细说明,只给出一些提示。</p>
<p>目标列表的删除将从左至右递归地删除每一个目标。</p>
<p id="index-22">名称的删除将从局部或全局命名空间中移除该名称的绑定,具体作用域的确定是看该名称是否有在同一代码块的 <a class="reference internal" href="#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> 语句中出现。 如果该名称未被绑定,将会引发 <a class="reference internal" href="../library/exceptions.html#NameError" title="NameError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">NameError</span></code></a></p>
<p id="index-23">属性引用、抽取和切片的删除会被传递给相应的原型对象;删除一个切片基本等价于赋值为一个右侧类型的空切片(但即便这一点也是由切片对象决定的)。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.2 版更改: </span>在之前版本中,如果一个名称作为被嵌套代码块中的自由变量出现,则将其从局部命名空间中删除是非法的。</p>
</div>
</section>
<section id="the-return-statement">
<span id="return"></span><h2><span class="section-number">7.6. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句<a class="headerlink" href="#the-return-statement" title="永久链接至标题"></a></h2>
<pre id="index-24">
<strong id="grammar-token-return-stmt">return_stmt</strong> ::= &quot;return&quot; [<a class="reference internal" href="expressions.html#grammar-token-expression-list"><code class="xref docutils literal notranslate"><span class="pre">expression_list</span></code></a>]
</pre>
<p><a class="reference internal" href="#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a> 在语法上只会出现于函数定义所嵌套的代码,不会出现于类定义所嵌套的代码。</p>
<p>如果提供了表达式列表,它将被求值,否则以 <code class="docutils literal notranslate"><span class="pre">None</span></code> 替代。</p>
<p><a class="reference internal" href="#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a> 会离开当前函数调用,并以表达式列表 (或 <code class="docutils literal notranslate"><span class="pre">None</span></code>) 作为返回值。</p>
<p id="index-25"><a class="reference internal" href="#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a> 将控制流传出一个带有 <a class="reference internal" href="compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句的 <a class="reference internal" href="compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句时,该 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句会先被执行然后再真正离开该函数。</p>
<p>在一个生成器函数中,<a class="reference internal" href="#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a> 语句表示生成器已完成并将导致 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 被引发。 返回值(如果有的话)会被当作一个参数用来构建 <a class="reference internal" href="../library/exceptions.html#StopIteration" title="StopIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopIteration</span></code></a> 并成为 <code class="xref py py-attr docutils literal notranslate"><span class="pre">StopIteration.value</span></code> 属性。</p>
<p>在一个异步生成器函数中,一个空的 <a class="reference internal" href="#return"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code></a> 语句表示异步生成器已完成并将导致 <a class="reference internal" href="../library/exceptions.html#StopAsyncIteration" title="StopAsyncIteration"><code class="xref py py-exc docutils literal notranslate"><span class="pre">StopAsyncIteration</span></code></a> 被引发。 一个非空的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句在异步生成器函数中会导致语法错误。</p>
</section>
<section id="the-yield-statement">
<span id="yield"></span><h2><span class="section-number">7.7. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code> 语句<a class="headerlink" href="#the-yield-statement" title="永久链接至标题"></a></h2>
<pre id="index-26">
<strong id="grammar-token-yield-stmt">yield_stmt</strong> ::= <a class="reference internal" href="expressions.html#grammar-token-yield-expression"><code class="xref docutils literal notranslate"><span class="pre">yield_expression</span></code></a>
</pre>
<p><a class="reference internal" href="#yield"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code></a> 语句在语义上等同于 <a class="reference internal" href="expressions.html#yieldexpr"><span class="std std-ref">yield 表达式</span></a>。 yield 语句可用来省略在使用等效的 yield 表达式语句时所必须的圆括号。 例如,以下 yield 语句</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">yield</span> <span class="o">&lt;</span><span class="n">expr</span><span class="o">&gt;</span>
<span class="k">yield from</span> <span class="o">&lt;</span><span class="n">expr</span><span class="o">&gt;</span>
</pre></div>
</div>
<p>等同于以下 yield 表达式语句</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="p">(</span><span class="k">yield</span> <span class="o">&lt;</span><span class="n">expr</span><span class="o">&gt;</span><span class="p">)</span>
<span class="p">(</span><span class="k">yield from</span> <span class="o">&lt;</span><span class="n">expr</span><span class="o">&gt;</span><span class="p">)</span>
</pre></div>
</div>
<p>yield 表达式和语句仅在定义 <a class="reference internal" href="../glossary.html#term-generator"><span class="xref std std-term">generator</span></a> 函数时使用,并且仅被用于生成器函数的函数体内部。 在函数定义中使用 yield 就足以使得该定义创建的是生成器函数而非普通函数。</p>
<p>有关 <a class="reference internal" href="#yield"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code></a> 语义的完整细节请参看 <a class="reference internal" href="expressions.html#yieldexpr"><span class="std std-ref">yield 表达式</span></a> 一节。</p>
</section>
<section id="the-raise-statement">
<span id="raise"></span><h2><span class="section-number">7.8. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code> 语句<a class="headerlink" href="#the-raise-statement" title="永久链接至标题"></a></h2>
<pre id="index-27">
<strong id="grammar-token-raise-stmt">raise_stmt</strong> ::= &quot;raise&quot; [<a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a> [&quot;from&quot; <a class="reference internal" href="expressions.html#grammar-token-expression"><code class="xref docutils literal notranslate"><span class="pre">expression</span></code></a>]]
</pre>
<p>如果不带表达式,<a class="reference internal" href="#raise"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code></a> 会重新引发当前作用域内最后一个激活的异常。 如果当前作用域内没有激活的异常,将会引发 <a class="reference internal" href="../library/exceptions.html#RuntimeError" title="RuntimeError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">RuntimeError</span></code></a> 来提示错误。</p>
<p>否则的话,<a class="reference internal" href="#raise"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code></a> 会将第一个表达式求值为异常对象。 它必须为 <a class="reference internal" href="../library/exceptions.html#BaseException" title="BaseException"><code class="xref py py-class docutils literal notranslate"><span class="pre">BaseException</span></code></a> 的子类或实例。 如果它是一个类,当需要时会通过不带参数地实例化该类来获得异常的实例。</p>
<p>异常的 <em class="dfn">类型</em> 为异常实例的类,<em class="dfn"></em> 为实例本身。</p>
<p id="index-28">当异常被引发时通常会自动创建一个回溯对象并将其关联到可写的 <code class="xref py py-attr docutils literal notranslate"><span class="pre">__traceback__</span></code> 属性。 你可以创建一个异常并同时使用 <code class="xref py py-meth docutils literal notranslate"><span class="pre">with_traceback()</span></code> 异常方法(该方法将返回同一异常实例,并将回溯对象设为其参数)设置自己的回溯,就像这样:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="k">raise</span> <span class="ne">Exception</span><span class="p">(</span><span class="s2">&quot;foo occurred&quot;</span><span class="p">)</span><span class="o">.</span><span class="n">with_traceback</span><span class="p">(</span><span class="n">tracebackobj</span><span class="p">)</span>
</pre></div>
</div>
<p id="index-29"><code class="docutils literal notranslate"><span class="pre">from</span></code> 子句用于异常串连:如果有该子句,则第二个 <em>表达式</em> 必须为另一个异常类或实例。 如果第二个表达式是一个异常实例,它将作为可写的 <code class="xref py py-attr docutils literal notranslate"><span class="pre">__cause__</span></code> 属性被关联到所引发的异常。 如果该表达式是一个异常类,这个类将被实例化且所生成的异常实例将作为 <code class="xref py py-attr docutils literal notranslate"><span class="pre">__cause__</span></code> 属性被关联到所引发的异常。 如果所引发的异常未被处理,则两个异常都将被打印出来:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="mi">1</span> <span class="o">/</span> <span class="mi">0</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">exc</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Something bad happened&quot;</span><span class="p">)</span> <span class="kn">from</span> <span class="nn">exc</span>
<span class="gp">...</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">2</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">ZeroDivisionError</span>: <span class="n">division by zero</span>
<span class="gt">The above exception was the direct cause of the following exception:</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">4</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">RuntimeError</span>: <span class="n">Something bad happened</span>
</pre></div>
</div>
<p>如果一个异常在异常处理器或 <a class="reference internal" href="compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> clause: 中被引发,类似的机制会隐式地发挥作用,之前的异常将被关联到新异常的 <code class="xref py py-attr docutils literal notranslate"><span class="pre">__context__</span></code> 属性:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="mi">1</span> <span class="o">/</span> <span class="mi">0</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Something bad happened&quot;</span><span class="p">)</span>
<span class="gp">...</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">2</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">ZeroDivisionError</span>: <span class="n">division by zero</span>
<span class="gt">During handling of the above exception, another exception occurred:</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">4</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">RuntimeError</span>: <span class="n">Something bad happened</span>
</pre></div>
</div>
<p>异常串连可通过在 <code class="docutils literal notranslate"><span class="pre">from</span></code> 子句中指定 <a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 来显式地加以抑制:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="gp">&gt;&gt;&gt; </span><span class="k">try</span><span class="p">:</span>
<span class="gp">... </span> <span class="nb">print</span><span class="p">(</span><span class="mi">1</span> <span class="o">/</span> <span class="mi">0</span><span class="p">)</span>
<span class="gp">... </span><span class="k">except</span><span class="p">:</span>
<span class="gp">... </span> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">&quot;Something bad happened&quot;</span><span class="p">)</span> <span class="kn">from</span> <span class="kc">None</span>
<span class="gp">...</span>
<span class="gt">Traceback (most recent call last):</span>
File <span class="nb">&quot;&lt;stdin&gt;&quot;</span>, line <span class="m">4</span>, in <span class="n">&lt;module&gt;</span>
<span class="gr">RuntimeError</span>: <span class="n">Something bad happened</span>
</pre></div>
</div>
<p>有关异常的更多信息可在 <a class="reference internal" href="executionmodel.html#exceptions"><span class="std std-ref">异常</span></a> 一节查看,有关处理异常的信息可在 <a class="reference internal" href="compound_stmts.html#try"><span class="std std-ref">try 语句</span></a> 一节查看。</p>
<div class="versionchanged">
<p><span class="versionmodified changed">在 3.3 版更改: </span><a class="reference internal" href="../library/constants.html#None" title="None"><code class="xref py py-const docutils literal notranslate"><span class="pre">None</span></code></a> 现在允许被用作 <code class="docutils literal notranslate"><span class="pre">raise</span> <span class="pre">X</span> <span class="pre">from</span> <span class="pre">Y</span></code> 中的 <code class="docutils literal notranslate"><span class="pre">Y</span></code></p>
</div>
<div class="versionadded">
<p><span class="versionmodified added">3.3 新版功能: </span>使用 <code class="docutils literal notranslate"><span class="pre">__suppress_context__</span></code> 属性来抑制异常上下文的自动显示。</p>
</div>
</section>
<section id="the-break-statement">
<span id="break"></span><h2><span class="section-number">7.9. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code> 语句<a class="headerlink" href="#the-break-statement" title="永久链接至标题"></a></h2>
<pre id="index-30">
<strong id="grammar-token-break-stmt">break_stmt</strong> ::= &quot;break&quot;
</pre>
<p><a class="reference internal" href="#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a> 在语法上只会出现于 <a class="reference internal" href="compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a><a class="reference internal" href="compound_stmts.html#while"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code></a> 循环所嵌套的代码,但不会出现于该循环内部的函数或类定义所嵌套的代码。</p>
<p id="index-31">它会终结最近的外层循环,如果循环有可选的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">else</span></code> 子句,也会跳过该子句。</p>
<p>如果一个 <a class="reference internal" href="compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> 循环被 <a class="reference internal" href="#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a> 所终结,该循环的控制目标会保持其当前值。</p>
<p id="index-32"><a class="reference internal" href="#break"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code></a> 将控制流传出一个带有 <a class="reference internal" href="compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句的 <a class="reference internal" href="compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句时,该 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句会先被执行然后再真正离开该循环。</p>
</section>
<section id="the-continue-statement">
<span id="continue"></span><h2><span class="section-number">7.10. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code> 语句<a class="headerlink" href="#the-continue-statement" title="永久链接至标题"></a></h2>
<pre id="index-33">
<strong id="grammar-token-continue-stmt">continue_stmt</strong> ::= &quot;continue&quot;
</pre>
<p><a class="reference internal" href="#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> 在语法上只会出现于 <a class="reference internal" href="compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a><a class="reference internal" href="compound_stmts.html#while"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">while</span></code></a> 循环所嵌套的代码中,但不会出现于该循环内部的函数或类定义中。 它会继续执行最近的外层循环的下一个轮次。</p>
<p><a class="reference internal" href="#continue"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code></a> 将控制流传出一个带有 <a class="reference internal" href="compound_stmts.html#finally"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code></a> 子句的 <a class="reference internal" href="compound_stmts.html#try"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">try</span></code></a> 语句时,该 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">finally</span></code> 子句会先被执行然后再真正开始循环的下一个轮次。</p>
</section>
<section id="the-import-statement">
<span id="from"></span><span id="import"></span><h2><span class="section-number">7.11. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code> 语句<a class="headerlink" href="#the-import-statement" title="永久链接至标题"></a></h2>
<pre id="index-34">
<strong id="grammar-token-import-stmt">import_stmt </strong> ::= &quot;import&quot; <a class="reference internal" href="#grammar-token-module"><code class="xref docutils literal notranslate"><span class="pre">module</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>] (&quot;,&quot; <a class="reference internal" href="#grammar-token-module"><code class="xref docutils literal notranslate"><span class="pre">module</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>])*
| &quot;from&quot; <a class="reference internal" href="#grammar-token-relative-module"><code class="xref docutils literal notranslate"><span class="pre">relative_module</span></code></a> &quot;import&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>]
(&quot;,&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>])*
| &quot;from&quot; <a class="reference internal" href="#grammar-token-relative-module"><code class="xref docutils literal notranslate"><span class="pre">relative_module</span></code></a> &quot;import&quot; &quot;(&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>]
(&quot;,&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>])* [&quot;,&quot;] &quot;)&quot;
| &quot;from&quot; <a class="reference internal" href="#grammar-token-module"><code class="xref docutils literal notranslate"><span class="pre">module</span></code></a> &quot;import&quot; &quot;*&quot;
<strong id="grammar-token-module">module </strong> ::= (<a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> &quot;.&quot;)* <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>
<strong id="grammar-token-relative-module">relative_module</strong> ::= &quot;.&quot;* <a class="reference internal" href="#grammar-token-module"><code class="xref docutils literal notranslate"><span class="pre">module</span></code></a> | &quot;.&quot;+
</pre>
<p>基本的 import 语句(不带 <a class="reference internal" href="#from"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">from</span></code></a> 子句)会分两步执行:</p>
<ol class="arabic simple">
<li><p>查找一个模块,如果有必要还会加载并初始化模块。</p></li>
<li><p>在局部命名空间中为 <a class="reference internal" href="#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句发生位置所处的作用域定义一个或多个名称。</p></li>
</ol>
<p>当语句包含多个子句(由逗号分隔)时这两个步骤将对每个子句分别执行,如同这些子句被分成独立的 import 语句一样。</p>
<p>第一个步骤即查找和加载模块的详情 <a class="reference internal" href="import.html#importsystem"><span class="std std-ref">导入系统</span></a> 一节中有更详细的描述,其中也描述了可被导入的多种类型的包和模块,以及可用于定制导入系统的所有钩子对象。 请注意这一步如果失败,则可能说明模块无法找到,<em>或者</em> 是在初始化模块,包括执行模块代码期间发生了错误。</p>
<p>如果成功获取到请求的模块,则可以通过以下三种方式一之在局部命名空间中使用它:</p>
<ul class="simple" id="index-35">
<li><p>模块名后使用 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">as</span></code> 时,直接把 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">as</span></code> 后的名称与导入模块绑定。</p></li>
<li><p>如果没有指定其他名称,且被导入的模块为最高层级模块,则模块的名称将被绑定到局部命名空间作为对所导入模块的引用。</p></li>
<li><p>如果被导入的模块 <em>不是</em> 最高层级模块,则包含该模块的最高层级包的名称将被绑定到局部命名空间作为对该最高层级包的引用。 所导入的模块必须使用其完整限定名称来访问而不能直接访问。</p></li>
</ul>
<p id="index-36"><a class="reference internal" href="#from"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">from</span></code></a> 形式使用的过程略微繁复一些:</p>
<ol class="arabic simple">
<li><p>查找 <a class="reference internal" href="#from"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">from</span></code></a> 子句中指定的模块,如有必要还会加载并初始化模块;</p></li>
<li><p>对于 <a class="reference internal" href="#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 子句中指定的每个标识符:</p>
<ol class="arabic simple">
<li><p>检查被导入模块是否有该名称的属性</p></li>
<li><p>如果没有,尝试导入具有该名称的子模块,然后再次检查被导入模块是否有该属性</p></li>
<li><p>如果未找到该属性,则引发 <a class="reference internal" href="../library/exceptions.html#ImportError" title="ImportError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">ImportError</span></code></a></p></li>
<li><p>否则的话,将对该值的引用存入局部命名空间,如果有 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">as</span></code> 子句则使用其指定的名称,否则使用该属性的名称</p></li>
</ol>
</li>
</ol>
<p>示例:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">foo</span> <span class="c1"># foo imported and bound locally</span>
<span class="kn">import</span> <span class="nn">foo.bar.baz</span> <span class="c1"># foo.bar.baz imported, foo bound locally</span>
<span class="kn">import</span> <span class="nn">foo.bar.baz</span> <span class="k">as</span> <span class="nn">fbb</span> <span class="c1"># foo.bar.baz imported and bound as fbb</span>
<span class="kn">from</span> <span class="nn">foo.bar</span> <span class="kn">import</span> <span class="n">baz</span> <span class="c1"># foo.bar.baz imported and bound as baz</span>
<span class="kn">from</span> <span class="nn">foo</span> <span class="kn">import</span> <span class="n">attr</span> <span class="c1"># foo imported and foo.attr bound as attr</span>
</pre></div>
</div>
<p id="index-37">如果标识符列表改为一个星号 (<code class="docutils literal notranslate"><span class="pre">'*'</span></code>),则在模块中定义的全部公有名称都将按 <a class="reference internal" href="#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句所在的作用域被绑定到局部命名空间。</p>
<p id="index-38">一个模块所定义的 <em>公有名称</em> 是由在模块的命名空间中检测一个名为 <code class="docutils literal notranslate"><span class="pre">__all__</span></code> 的变量来确定的;如果有定义,它必须是一个字符串列表,其中的项为该模块所定义或导入的名称。 在 <code class="docutils literal notranslate"><span class="pre">__all__</span></code> 中所给出的名称都会被视为公有并且应当存在。 如果 <code class="docutils literal notranslate"><span class="pre">__all__</span></code> 没有被定义,则公有名称的集合将包含在模块的命名空间中找到的所有不以下划线字符 (<code class="docutils literal notranslate"><span class="pre">'_'</span></code>) 打头的名称。 <code class="docutils literal notranslate"><span class="pre">__all__</span></code> 应当包括整个公有 API。 它的目标是避免意外地导出不属于 API 的一部分的项(例如在模块内部被导入和使用的库模块)。</p>
<p>通配符形式的导入 --- <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">module</span> <span class="pre">import</span> <span class="pre">*</span></code> --- 仅在模块层级上被允许。 尝试在类或函数定义中使用它将引发 <a class="reference internal" href="../library/exceptions.html#SyntaxError" title="SyntaxError"><code class="xref py py-exc docutils literal notranslate"><span class="pre">SyntaxError</span></code></a></p>
<p id="index-39">当指定要导入哪个模块时,你不必指定模块的绝对名称。 当一个模块或包被包含在另一个包之中时,可以在同一个最高层级包中进行相对导入,而不必提及包名称。 通过在 <a class="reference internal" href="#from"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">from</span></code></a> 之后指定的模块或包中使用前缀点号,你可以在不指定确切名称的情况下指明在当前包层级结构中要上溯多少级。 一个前缀点号表示是执行导入的模块所在的当前包,两个点号表示上溯一个包层级。 三个点号表示上溯两级,依此类推。 因此如果你执行 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">.</span> <span class="pre">import</span> <span class="pre">mod</span></code> 时所处位置为 <code class="docutils literal notranslate"><span class="pre">pkg</span></code> 包内的一个模块,则最终你将导入 <code class="docutils literal notranslate"><span class="pre">pkg.mod</span></code>。 如果你执行 <code class="docutils literal notranslate"><span class="pre">from</span> <span class="pre">..subpkg2</span> <span class="pre">import</span> <span class="pre">mod</span></code> 时所处位置为 <code class="docutils literal notranslate"><span class="pre">pkg.subpkg1</span></code> 则你将导入 <code class="docutils literal notranslate"><span class="pre">pkg.subpkg2.mod</span></code>。 有关相对导入的规范说明包含在 <a class="reference internal" href="import.html#relativeimports"><span class="std std-ref">包相对导入</span></a> 一节中。</p>
<p><a class="reference internal" href="../library/importlib.html#importlib.import_module" title="importlib.import_module"><code class="xref py py-func docutils literal notranslate"><span class="pre">importlib.import_module()</span></code></a> 被提供用来为动态地确定要导入模块的应用提供支持。</p>
<p class="audit-hook">引发一个 <a class="reference internal" href="../library/sys.html#auditing"><span class="std std-ref">审计事件</span></a> <code class="docutils literal notranslate"><span class="pre">import</span></code> 并附带参数 <code class="docutils literal notranslate"><span class="pre">module</span></code>, <code class="docutils literal notranslate"><span class="pre">filename</span></code>, <code class="docutils literal notranslate"><span class="pre">sys.path</span></code>, <code class="docutils literal notranslate"><span class="pre">sys.meta_path</span></code>, <code class="docutils literal notranslate"><span class="pre">sys.path_hooks</span></code></p>
<section id="future-statements">
<span id="future"></span><h3><span class="section-number">7.11.1. </span>future 语句<a class="headerlink" href="#future-statements" title="永久链接至标题"></a></h3>
<p id="index-40"><em class="dfn">future 语句</em> 是一种针对编译器的指令,指明某个特定模块应当使用在特定的未来某个 Python 发行版中成为标准特性的语法或语义。</p>
<p>future 语句的目的是使得向在语言中引入了不兼容改变的 Python 未来版本的迁移更为容易。 它允许基于每个模块在某种新特性成为标准之前的发行版中使用该特性。</p>
<pre>
<strong id="grammar-token-future-stmt">future_stmt</strong> ::= &quot;from&quot; &quot;__future__&quot; &quot;import&quot; <a class="reference internal" href="#grammar-token-feature"><code class="xref docutils literal notranslate"><span class="pre">feature</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>]
(&quot;,&quot; <a class="reference internal" href="#grammar-token-feature"><code class="xref docutils literal notranslate"><span class="pre">feature</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>])*
| &quot;from&quot; &quot;__future__&quot; &quot;import&quot; &quot;(&quot; <a class="reference internal" href="#grammar-token-feature"><code class="xref docutils literal notranslate"><span class="pre">feature</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>]
(&quot;,&quot; <a class="reference internal" href="#grammar-token-feature"><code class="xref docutils literal notranslate"><span class="pre">feature</span></code></a> [&quot;as&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>])* [&quot;,&quot;] &quot;)&quot;
<strong id="grammar-token-feature">feature </strong> ::= <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>
</pre>
<p>future 语句必须在靠近模块开头的位置出现。 可以出现在 future 语句之前行只有:</p>
<ul class="simple">
<li><p>模块的文档字符串(如果存在),</p></li>
<li><p>注释,</p></li>
<li><p>空行,以及</p></li>
<li><p>其他 future 语句。</p></li>
</ul>
<p>唯一需要使用 future 语句的特性是 <code class="docutils literal notranslate"><span class="pre">标注</span></code> (参见 <span class="target" id="index-56"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0563"><strong>PEP 563</strong></a>)。</p>
<p>future 语句所启用的所有历史特性仍然为 Python 3 所认可。 其中包括 <code class="docutils literal notranslate"><span class="pre">absolute_import</span></code>, <code class="docutils literal notranslate"><span class="pre">division</span></code>, <code class="docutils literal notranslate"><span class="pre">generators</span></code>, <code class="docutils literal notranslate"><span class="pre">generator_stop</span></code>, <code class="docutils literal notranslate"><span class="pre">unicode_literals</span></code>, <code class="docutils literal notranslate"><span class="pre">print_function</span></code>, <code class="docutils literal notranslate"><span class="pre">nested_scopes</span></code><code class="docutils literal notranslate"><span class="pre">with_statement</span></code>。 它们都已成为冗余项,因为它们总是为已启用状态,保留它们只是为了向后兼容。</p>
<p>future 语句在编译时会被识别并做特殊对待:对核心构造语义的改变常常是通过生成不同的代码来实现。 新的特性甚至可能会引入新的不兼容语法(例如新的保留字),在这种情况下编译器可能需要以不同的方式来解析模块。 这样的决定不能推迟到运行时方才作出。</p>
<p>对于任何给定的发布版本,编译器要知道哪些特性名称已被定义,如果某个 future 语句包含未知的特性则会引发编译时错误。</p>
<p>直接运行时的语义与任何 import 语句相同:存在一个后文将详细说明的标准模块 <a class="reference internal" href="../library/__future__.html#module-__future__" title="__future__: Future statement definitions"><code class="xref py py-mod docutils literal notranslate"><span class="pre">__future__</span></code></a>,它会在执行 future 语句时以通常的方式被导入。</p>
<p>相应的运行时语义取决于 future 语句所启用的指定特性。</p>
<p>请注意以下语句没有任何特别之处:</p>
<div class="highlight-python3 notranslate"><div class="highlight"><pre><span></span><span class="kn">import</span> <span class="nn">__future__</span> <span class="p">[</span><span class="k">as</span> <span class="n">name</span><span class="p">]</span>
</pre></div>
</div>
<p>这并非 future 语句;它只是一条没有特殊语义或语法限制的普通 import 语句。</p>
<p>在默认情况下通过对Code compiled by calls to the 内置函数 <a class="reference internal" href="../library/functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a><a class="reference internal" href="../library/functions.html#compile" title="compile"><code class="xref py py-func docutils literal notranslate"><span class="pre">compile()</span></code></a> 的调用所编译的代码如果出现于一个包含有 future 语句的模块 <code class="xref py py-mod docutils literal notranslate"><span class="pre">M</span></code> 之中,就会使用 future 语句所关联的语法和语义。 此行为可以通过 <a class="reference internal" href="../library/functions.html#compile" title="compile"><code class="xref py py-func docutils literal notranslate"><span class="pre">compile()</span></code></a> 的可选参数加以控制 --- 请参阅该函数的文档以了解详情。</p>
<p>在交互式解释器提示符中键入的 future 语句将在解释器会话此后的交互中有效。 如果一个解释器的启动使用了 <a class="reference internal" href="../using/cmdline.html#cmdoption-i"><code class="xref std std-option docutils literal notranslate"><span class="pre">-i</span></code></a> 选项启动,并传入了一个脚本名称来执行,且该脚本包含 future 语句,它将在交互式会话开始执行脚本之后保持有效。</p>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-57"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-0236"><strong>PEP 236</strong></a> - 回到 __future__</dt><dd><p>有关 __future__ 机制的最初提议。</p>
</dd>
</dl>
</div>
</section>
</section>
<section id="the-global-statement">
<span id="global"></span><h2><span class="section-number">7.12. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句<a class="headerlink" href="#the-global-statement" title="永久链接至标题"></a></h2>
<pre id="index-43">
<strong id="grammar-token-global-stmt">global_stmt</strong> ::= &quot;global&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> (&quot;,&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>)*
</pre>
<p><a class="reference internal" href="#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> 语句是作用于整个当前代码块的声明。 它意味着所列出的标识符将被解读为全局变量。 要给全局变量赋值不可能不用到 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 关键字,不过自由变量也可以指向全局变量而不必声明为全局变量。</p>
<p><a class="reference internal" href="#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> 语句中列出的名称不得在同一代码块内该 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句之前的位置中使用。</p>
<p><a class="reference internal" href="#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> 语句中列出的名称不能被定义为形式参数,也不能在 <a class="reference internal" href="compound_stmts.html#for"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">for</span></code></a> 循环的控制目标、<a class="reference internal" href="compound_stmts.html#class"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">class</span></code></a> 定义、函数定义、<a class="reference internal" href="#import"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code></a> 语句或变量标注中定义。</p>
<div class="impl-detail compound">
<p><strong>CPython implementation detail:</strong> 当前的实现并未强制要求所有的上述限制,但程序不应当滥用这样的自由,因为未来的实现可能会改为强制要求,并静默地改变程序的含义。</p>
</div>
<p id="index-44"><strong>程序员注意事项:</strong> <a class="reference internal" href="#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> 是对解析器的指令。 它仅对与 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句同时被解析的代码起作用。 特别地,包含在提供给内置 <a class="reference internal" href="../library/functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a> 函数字符串或代码对象中的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句并不会影响 <em>包含</em> 该函数调用的代码块,而包含在这种字符串中的代码也不会受到包含该函数调用的代码中的 <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句影响。 这同样适用于 <a class="reference internal" href="../library/functions.html#eval" title="eval"><code class="xref py py-func docutils literal notranslate"><span class="pre">eval()</span></code></a><a class="reference internal" href="../library/functions.html#compile" title="compile"><code class="xref py py-func docutils literal notranslate"><span class="pre">compile()</span></code></a> 函数。</p>
</section>
<section id="the-nonlocal-statement">
<span id="nonlocal"></span><h2><span class="section-number">7.13. </span><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code> 语句<a class="headerlink" href="#the-nonlocal-statement" title="永久链接至标题"></a></h2>
<pre id="index-45">
<strong id="grammar-token-nonlocal-stmt">nonlocal_stmt</strong> ::= &quot;nonlocal&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a> (&quot;,&quot; <a class="reference internal" href="lexical_analysis.html#grammar-token-identifier"><code class="xref docutils literal notranslate"><span class="pre">identifier</span></code></a>)*
</pre>
<p><a class="reference internal" href="#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> 语句会使得所列出的名称指向之前在最近的包含作用域中绑定的除全局变量以外的变量。 这种功能很重要,因为绑定的默认行为是先搜索局部命名空间。 这个语句允许被封装的代码重新绑定局部作用域以外且非全局(模块)作用域当中的变量。</p>
<p><a class="reference internal" href="#global"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code></a> 语句中列出的名称不同,<a class="reference internal" href="#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> 语句中列出的名称必须指向之前存在于包含作用域之中的绑定(在这个应当用来创建新绑定的作用域不能被无歧义地确定)。</p>
<p><a class="reference internal" href="#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> 语句中列出的名称不得与之前存在于局部作用域中的绑定相冲突。</p>
<div class="admonition seealso">
<p class="admonition-title">参见</p>
<dl class="simple">
<dt><span class="target" id="index-58"></span><a class="pep reference external" href="https://www.python.org/dev/peps/pep-3104"><strong>PEP 3104</strong></a> - 访问外层作用域中的名称</dt><dd><p>有关 <a class="reference internal" href="#nonlocal"><code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code></a> 语句的规范说明。</p>
</dd>
</dl>
</div>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">7. 简单语句</a><ul>
<li><a class="reference internal" href="#expression-statements">7.1. 表达式语句</a></li>
<li><a class="reference internal" href="#assignment-statements">7.2. 赋值语句</a><ul>
<li><a class="reference internal" href="#augmented-assignment-statements">7.2.1. 增强赋值语句</a></li>
<li><a class="reference internal" href="#annotated-assignment-statements">7.2.2. 带标注的赋值语句</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-assert-statement">7.3. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">assert</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-pass-statement">7.4. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">pass</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-del-statement">7.5. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">del</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-return-statement">7.6. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">return</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-yield-statement">7.7. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">yield</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-raise-statement">7.8. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">raise</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-break-statement">7.9. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">break</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-continue-statement">7.10. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">continue</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-import-statement">7.11. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">import</span></code> 语句</a><ul>
<li><a class="reference internal" href="#future-statements">7.11.1. future 语句</a></li>
</ul>
</li>
<li><a class="reference internal" href="#the-global-statement">7.12. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">global</span></code> 语句</a></li>
<li><a class="reference internal" href="#the-nonlocal-statement">7.13. <code class="xref std std-keyword docutils literal notranslate"><span class="pre">nonlocal</span></code> 语句</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="expressions.html"
title="上一章"><span class="section-number">6. </span>表达式</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="compound_stmts.html"
title="下一章"><span class="section-number">8. </span>复合语句</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/simple_stmts.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="compound_stmts.html" title="8. 复合语句"
>下一页</a> |</li>
<li class="right" >
<a href="expressions.html" title="6. 表达式"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>

View File

@@ -0,0 +1,310 @@
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" lang="zh_CN">
<head>
<meta charset="utf-8" /><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<title>9. 最高层级组件 &#8212; Python 3.8.20 文档</title><meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="../_static/pydoctheme.css" type="text/css" />
<link rel="stylesheet" href="../_static/pygments.css" type="text/css" />
<script id="documentation_options" data-url_root="../" src="../_static/documentation_options.js"></script>
<script src="../_static/jquery.js"></script>
<script src="../_static/underscore.js"></script>
<script src="../_static/doctools.js"></script>
<script src="../_static/language_data.js"></script>
<script src="../_static/translations.js"></script>
<script src="../_static/sidebar.js"></script>
<link rel="search" type="application/opensearchdescription+xml"
title="在 Python 3.8.20 文档 中搜索"
href="../_static/opensearch.xml"/>
<link rel="author" title="关于这些文档" href="../about.html" />
<link rel="index" title="索引" href="../genindex.html" />
<link rel="search" title="搜索" href="../search.html" />
<link rel="copyright" title="版权所有" href="../copyright.html" />
<link rel="next" title="10. 完整的语法规范" href="grammar.html" />
<link rel="prev" title="8. 复合语句" href="compound_stmts.html" />
<link rel="canonical" href="https://docs.python.org/3/reference/toplevel_components.html" />
<style>
@media only screen {
table.full-width-table {
width: 100%;
}
}
</style>
<link rel="shortcut icon" type="image/png" href="../_static/py.svg" />
<script type="text/javascript" src="../_static/copybutton.js"></script>
<script type="text/javascript" src="../_static/menu.js"></script>
</head>
<body>
<div class="mobile-nav">
<input type="checkbox" id="menuToggler" class="toggler__input" aria-controls="navigation"
aria-pressed="false" aria-expanded="false" role="button" aria-label="Menu" />
<label for="menuToggler" class="toggler__label">
<span></span>
</label>
<nav class="nav-content" role="navigation">
<a href="https://www.python.org/" class="nav-logo">
<img src="../_static/py.svg" alt="Logo"/>
</a>
<div class="version_switcher_placeholder"></div>
<form role="search" class="search" action="../search.html" method="get">
<svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" class="search-icon">
<path fill-rule="nonzero"
d="M15.5 14h-.79l-.28-.27a6.5 6.5 0 001.48-5.34c-.47-2.78-2.79-5-5.59-5.34a6.505 6.505 0 00-7.27 7.27c.34 2.8 2.56 5.12 5.34 5.59a6.5 6.5 0 005.34-1.48l.27.28v.79l4.25 4.25c.41.41 1.08.41 1.49 0 .41-.41.41-1.08 0-1.49L15.5 14zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14z" fill="#444"></path>
</svg>
<input type="text" name="q" aria-label="快速搜索"/>
<input type="submit" value="转向"/>
</form>
</nav>
<div class="menu-wrapper">
<nav class="menu" role="navigation" aria-label="main navigation">
<div class="language_switcher_placeholder"></div>
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">9. 最高层级组件</a><ul>
<li><a class="reference internal" href="#complete-python-programs">9.1. 完整的 Python 程序</a></li>
<li><a class="reference internal" href="#file-input">9.2. 文件输入</a></li>
<li><a class="reference internal" href="#interactive-input">9.3. 交互式输入</a></li>
<li><a class="reference internal" href="#expression-input">9.4. 表达式输入</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="compound_stmts.html"
title="上一章"><span class="section-number">8. </span>复合语句</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="grammar.html"
title="下一章"><span class="section-number">10. </span>完整的语法规范</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/toplevel_components.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</nav>
</div>
</div>
<div id="outdated-warning" style="padding: .5em; text-align: center; background-color: #FFBABA; color: #6A0E0E;">
这个文档所针对的是一个已不再受支持的 Python 旧版本。
你应当升级版本,并阅读
<a href="/3/reference/toplevel_components.html"> Python 当前稳定版本的文档</a>.
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
accesskey="I">索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="grammar.html" title="10. 完整的语法规范"
accesskey="N">下一页</a> |</li>
<li class="right" >
<a href="compound_stmts.html" title="8. 复合语句"
accesskey="P">上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" accesskey="U">Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="document">
<div class="documentwrapper">
<div class="bodywrapper">
<div class="body" role="main">
<section id="top-level-components">
<span id="top-level"></span><h1><span class="section-number">9. </span>最高层级组件<a class="headerlink" href="#top-level-components" title="永久链接至标题"></a></h1>
<p id="index-0">Python 解释器可以从多种源获得输入:作为标准输入或程序参数传入的脚本,以交互方式键入的语句,导入的模块源文件等等。 这一章将给出在这些情况下所用的语法。</p>
<section id="complete-python-programs">
<span id="programs"></span><h2><span class="section-number">9.1. </span>完整的 Python 程序<a class="headerlink" href="#complete-python-programs" title="永久链接至标题"></a></h2>
<span class="target" id="index-1"></span><p id="index-2">虽然语言规范描述不必规定如何发起调用语言解释器,但对完整的 Python 程序加以说明还是很有用的。 一个完整的 Python 程序会在最小初始化环境中被执行:所有内置和标准模块均为可用,但均处于未初始化状态,只有 <a class="reference internal" href="../library/sys.html#module-sys" title="sys: Access system-specific parameters and functions."><code class="xref py py-mod docutils literal notranslate"><span class="pre">sys</span></code></a> (各种系统服务), <a class="reference internal" href="../library/builtins.html#module-builtins" title="builtins: The module that provides the built-in namespace."><code class="xref py py-mod docutils literal notranslate"><span class="pre">builtins</span></code></a> (内置函数、异常以及 <code class="docutils literal notranslate"><span class="pre">None</span></code>) 和 <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a> 除外。 最后一个模块用于为完整程序的执行提供局部和全局命名空间。</p>
<p>适用于一个完整 Python 程序的语法即下节所描述的文件输入。</p>
<p id="index-3">解释器也可以通过交互模式被发起调用;在此情况下,它并不读取和执行一个完整程序,而是每次读取和执行一条语句(可能为复合语句)。 此时的初始环境与一个完整程序的相同;每条语句会在 <a class="reference internal" href="../library/__main__.html#module-__main__" title="__main__: The environment where the top-level script is run."><code class="xref py py-mod docutils literal notranslate"><span class="pre">__main__</span></code></a> 的命名空间中被执行。</p>
<p id="index-4">一个完整程序可通过三种形式被传递给解释器:使用 <a class="reference internal" href="../using/cmdline.html#cmdoption-c"><code class="xref std std-option docutils literal notranslate"><span class="pre">-c</span></code></a> <em>字符串</em> 命令行选项,使用一个文件作为第一个命令行参数,或者使用标准输入。 如果文件或标准输入是一个 tty 设置,解释器会进入交互模式;否则的话,它会将文件当作一个完整程序来执行。</p>
</section>
<section id="file-input">
<span id="id1"></span><h2><span class="section-number">9.2. </span>文件输入<a class="headerlink" href="#file-input" title="永久链接至标题"></a></h2>
<p>所有从非交互式文件读取的输入都具有相同的形式:</p>
<pre>
<strong id="grammar-token-file-input">file_input</strong> ::= (NEWLINE | <a class="reference internal" href="compound_stmts.html#grammar-token-statement"><code class="xref docutils literal notranslate"><span class="pre">statement</span></code></a>)*
</pre>
<p>此语法用于下列几种情况:</p>
<ul class="simple">
<li><p>解析一个完整 Python 程序时(从文件或字符串);</p></li>
<li><p>解析一个模块时;</p></li>
<li><p>解析一个传递给 <a class="reference internal" href="../library/functions.html#exec" title="exec"><code class="xref py py-func docutils literal notranslate"><span class="pre">exec()</span></code></a> 函数的字符串时;</p></li>
</ul>
</section>
<section id="interactive-input">
<span id="interactive"></span><h2><span class="section-number">9.3. </span>交互式输入<a class="headerlink" href="#interactive-input" title="永久链接至标题"></a></h2>
<p>交互模式下的输入使用以下语法进行解析:</p>
<pre>
<strong id="grammar-token-interactive-input">interactive_input</strong> ::= [<a class="reference internal" href="compound_stmts.html#grammar-token-stmt-list"><code class="xref docutils literal notranslate"><span class="pre">stmt_list</span></code></a>] NEWLINE | <a class="reference internal" href="compound_stmts.html#grammar-token-compound-stmt"><code class="xref docutils literal notranslate"><span class="pre">compound_stmt</span></code></a> NEWLINE
</pre>
<p>请注意在交互模式下一条(最高层级)复合语句必须带有一个空行;这对于帮助解析器确定输入的结束是必须的。</p>
</section>
<section id="expression-input">
<span id="id2"></span><h2><span class="section-number">9.4. </span>表达式输入<a class="headerlink" href="#expression-input" title="永久链接至标题"></a></h2>
<span class="target" id="index-5"></span><p id="index-6"><a class="reference internal" href="../library/functions.html#eval" title="eval"><code class="xref py py-func docutils literal notranslate"><span class="pre">eval()</span></code></a> 被用于表达式输入。 它会忽略开头的空白。 传递给 <a class="reference internal" href="../library/functions.html#eval" title="eval"><code class="xref py py-func docutils literal notranslate"><span class="pre">eval()</span></code></a> 的字符串参数必须具有以下形式:</p>
<pre>
<strong id="grammar-token-eval-input">eval_input</strong> ::= <a class="reference internal" href="expressions.html#grammar-token-expression-list"><code class="xref docutils literal notranslate"><span class="pre">expression_list</span></code></a> NEWLINE*
</pre>
</section>
</section>
</div>
</div>
</div>
<div class="sphinxsidebar" role="navigation" aria-label="main navigation">
<div class="sphinxsidebarwrapper">
<h3><a href="../contents.html">目录</a></h3>
<ul>
<li><a class="reference internal" href="#">9. 最高层级组件</a><ul>
<li><a class="reference internal" href="#complete-python-programs">9.1. 完整的 Python 程序</a></li>
<li><a class="reference internal" href="#file-input">9.2. 文件输入</a></li>
<li><a class="reference internal" href="#interactive-input">9.3. 交互式输入</a></li>
<li><a class="reference internal" href="#expression-input">9.4. 表达式输入</a></li>
</ul>
</li>
</ul>
<h4>上一个主题</h4>
<p class="topless"><a href="compound_stmts.html"
title="上一章"><span class="section-number">8. </span>复合语句</a></p>
<h4>下一个主题</h4>
<p class="topless"><a href="grammar.html"
title="下一章"><span class="section-number">10. </span>完整的语法规范</a></p>
<div role="note" aria-label="source link">
<h3>本页</h3>
<ul class="this-page-menu">
<li><a href="../bugs.html">报告 Bug</a></li>
<li>
<a href="https://github.com/python/cpython/blob/3.8/Doc/reference/toplevel_components.rst"
rel="nofollow">显示源代码
</a>
</li>
</ul>
</div>
</div>
</div>
<div class="clearer"></div>
</div>
<div class="related" role="navigation" aria-label="related navigation">
<h3>导航</h3>
<ul>
<li class="right" style="margin-right: 10px">
<a href="../genindex.html" title="总目录"
>索引</a></li>
<li class="right" >
<a href="../py-modindex.html" title="Python 模块索引"
>模块</a> |</li>
<li class="right" >
<a href="grammar.html" title="10. 完整的语法规范"
>下一页</a> |</li>
<li class="right" >
<a href="compound_stmts.html" title="8. 复合语句"
>上一页</a> |</li>
<li><img src="../_static/py.svg" alt="python logo" style="vertical-align: middle; margin-top: -1px"/></li>
<li><a href="https://www.python.org/">Python</a> &#187;</li>
<li class="switchers">
<div class="language_switcher_placeholder"></div>
<div class="version_switcher_placeholder"></div>
</li>
<li>
</li>
<li id="cpython-language-and-version">
<a href="../index.html">3.8.20 Documentation</a> &#187;
</li>
<li class="nav-item nav-item-1"><a href="index.html" >Python语言参考</a> &#187;</li>
<li class="right">
<div class="inline-search" role="search">
<form class="inline-search" action="../search.html" method="get">
<input placeholder="快速搜索" aria-label="快速搜索" type="text" name="q" />
<input type="submit" value="转向" />
<input type="hidden" name="check_keywords" value="yes" />
<input type="hidden" name="area" value="default" />
</form>
</div>
|
</li>
</ul>
</div>
<div class="footer">
&copy; <a href="../copyright.html">版权所有</a> 2001-2024, Python Software Foundation.
<br />
This page is licensed under the Python Software Foundation License Version 2.
<br />
Examples, recipes, and other code in the documentation are additionally licensed under the Zero Clause BSD License.
<br />
<br />
The Python Software Foundation is a non-profit corporation.
<a href="https://www.python.org/psf/donations/">Please donate.</a>
<br />
<br />
最后更新于 12月 09, 2024.
<a href="https://docs.python.org/3/bugs.html">Found a bug</a>?
<br />
Created using <a href="https://www.sphinx-doc.org/">Sphinx</a> 2.4.4.
</div>
</body>
</html>