- 2.1. 行结构
- 2.1.1. 逻辑行
- 2.1.2. 物理行
- 2.1.3. 注释
- 2.1.4. 编码声明
- 2.1.5. 显式的行拼接
- 2.1.6. 隐式的行拼接
- 2.1.7. 空白行
- 2.1.8. 缩进
- 2.1.9. 形符之间的空白
2.1. 行结构
一个 Python 程序可分为许多 逻辑行。
2.1.1. 逻辑行
逻辑行的结束是以 NEWLINE 形符表示的。语句不能跨越逻辑行的边界,除非其语法允许包含 NEWLINE (例如复合语句可由多行子语句组成)。一个逻辑行可由一个或多个 物理行 按照明确或隐含的 行拼接 规则构成。
2.1.2. 物理行
物理行是以一个行终止序列结束的字符序列。在源文件和字符串中,可以使用任何标准平台上的行终止序列 - Unix 所用的 ASCII 字符 LF (换行), Windows 所用的 ASCII 字符序列 CR LF (回车加换行), 或者旧 Macintosh 所用的 ASCII 字符 CR (回车)。所有这些形式均可使用,无论具体平台。输入的结束也会被作为最后一个物理行的隐含终止标志。
当嵌入 Python 时,源码字符串传入 Python API 应使用标准 C 的传统换行符 (即 \n
,表示 ASCII 字符 LF 作为行终止标志)。
2.1.3. 注释
一条注释以不包含在字符串字面值内的井号 (#
) 开头,并在物理行的末尾结束。 一条注释标志着逻辑行的结束,除非存在隐含的行拼接规则。 注释在语法分析中会被忽略。
2.1.4. 编码声明
如果一条注释位于 Python 脚本的第一或第二行,并且匹配正则表达式 coding[=:]\s*([-\w.]+)
,这条注释会被作为编码声明来处理;上述表达式的第一组指定了源码文件的编码。编码声明必须独占一行。如果它是在第二行,则第一行也必须是注释。推荐的编码声明形式如下
- # -*- coding: <encoding-name> -*-
这也是 GNU Emacs 认可的形式,以及
- # vim:fileencoding=<encoding-name>
这是 Bram Moolenaar 的 VIM 认可的形式。
如果没有编码声明,则默认编码为 UTF-8。此外,如果文件的首字节为 UTF-8 字节顺序标志 (b'\xef\xbb\xbf'
),文件编码也声明为 UTF-8 (这是 Microsoft 的 notepad 等软件支持的形式)。
编码声明指定的编码名称必须是 Python 所认可的编码。所有词法分析将使用此编码,包括语义字符串、注释和标识符。
2.1.5. 显式的行拼接
两个或更多个物理行可使用反斜杠字符 (\
) 拼接为一个逻辑行,规则如下: 当一个物理行以一个不在字符串或注释内的反斜杠结尾时,它将与下一行拼接构成一个单独的逻辑行,反斜杠及其后的换行符会被删除。例如:
- if 1900 < year < 2100 and 1 <= month <= 12 \
- and 1 <= day <= 31 and 0 <= hour < 24 \
- and 0 <= minute < 60 and 0 <= second < 60: # Looks like a valid date
- return 1
以反斜杠结束的行不能带有注释。反斜杠不能用来拼接注释。反斜杠不能用来拼接形符,字符串除外 (即原文字符串以外的形符不能用反斜杠分隔到两个物理行)。不允许有原文字符串以外的反斜杠存在于物理行的其他位置。
2.1.6. 隐式的行拼接
圆括号、方括号或花括号以内的表达式允许分成多个物理行,无需使用反斜杠。例如:
- month_names = ['Januari', 'Februari', 'Maart', # These are the
- 'April', 'Mei', 'Juni', # Dutch names
- 'Juli', 'Augustus', 'September', # for the months
- 'Oktober', 'November', 'December'] # of the year
隐式的行拼接可以带有注释。后续行的缩进不影响程序结构。后续行也允许为空白行。隐式拼接的行之间不会有 NEWLINE 形符。隐式拼接的行也可以出现于三引号字符串中 (见下);此情况下这些行不允许带有注释。
2.1.7. 空白行
一个只包含空格符,制表符,进纸符或者注释的逻辑行会被忽略 (即不生成 NEWLINE 形符)。在交互模式输入语句时,对空白行的处理可能会因读取-求值-打印循环的具体实现方式而存在差异。在标准交互模式解释器中,一个完全空白的逻辑行 (即连空格或注释都没有) 将会结束一条多行复合语句。
2.1.8. 缩进
一个逻辑行开头处的空白 (空格符和制表符) 被用来计算该行的缩进等级,以决定语句段落的组织结构。
制表符会被 (从左至右) 替换为一至八个空格,这样缩进的空格总数为八的倍数 (这是为了与 Unix 所用的规则一致)。首个非空白字符之前的空格总数将确定该行的缩进层次。一个缩进不可使用反斜杠进行多行拼接;首个反斜杠之前的空格将确定缩进层次。
在一个源文件中如果混合使用制表符和空格符缩进,并使得确定缩进层次需要依赖于制表符对应的空格数量设置,则被视为不合规则;此情况将会引发 TabError
。
跨平台兼容性注释: 由于非 UNIX 平台上文本编辑器本身的特性,在一个源文件中混合使用制表符和空格符是不明智的。另外也要注意不同平台还可能会显式地限制最大缩进层级。
行首有时可能会有一个进纸符;它在上述缩进层级计算中会被忽略。处于行首空格内其他位置的进纸符的效果未定义 (例如它可能导致空格计数重置为零)。
多个连续行各自的缩进层级将会被放入一个堆栈用来生成 INDENT 和 DEDENT 形符,具体说明如下。
在读取文件的第一行之前,先向堆栈推入一个零值;它将不再被弹出。被推入栈的层级数值从底至顶持续增加。每个逻辑行开头的行缩进层级将与栈顶行比较。如果相同,则不做处理。如果新行层级较高,则会被推入栈顶,并生成一个 INDENT 形符。如果新行层级较低,则 应当 是栈中的层级数值之一;栈中高于该层级的所有数值都将被弹出,每弹出一级数值生成一个 DEDENT 形符。在文件末尾,栈中剩余的每个大于零的数值生成一个 DEDENT 形符。
这是一个正确 (但令人迷惑) 的Python 代码缩进示例:
- def perm(l):
- # Compute the list of all permutations of l
- if len(l) <= 1:
- return [l]
- r = []
- for i in range(len(l)):
- s = l[:i] + l[i+1:]
- p = perm(s)
- for x in p:
- r.append(l[i:i+1] + x)
- return r
以下示例显示了各种缩进错误:
- def perm(l): # error: first line indented
- for i in range(len(l)): # error: not indented
- s = l[:i] + l[i+1:]
- p = perm(l[:i] + l[i+1:]) # error: unexpected indent
- for x in p:
- r.append(l[i:i+1] + x)
- return r # error: inconsistent dedent
(实际上,前三个错误会被解析器发现;只有最后一个错误是由词法分析器发现的 —- return r
的缩进无法匹配弹出栈的缩进层级。)
2.1.9. 形符之间的空白
除非是在逻辑行的开头或字符串内,空格符、制表符和进纸符等空白符都同样可以用来分隔形符。如果两个形符彼此相连会被解析为一个不同的形符,则需要使用空白来分隔 (例如 ab 是一个形符,而 a b 是两个形符)。