Python行结构

2023-10-19 241

Python程序可以拆分为多个逻辑行,以提高代码的可读性和可维护性。

一、逻辑行

NEWLINE 形符表示结束逻辑行。语句不能超出逻辑行的边界,除非句法支持 NEWLINE (例如,复合语句中的多行子语句)。根据显式或隐式 行拼接 规则,一个或多个 物理行 可组成逻辑行。

二、物理行

物理行是由一序列字符组成,由行尾序列终止。源文件和字符串可以使用任意标准平台的行终止序列,包括 Unix ASCII 字符 LF(换行)、Windows ASCII 字符序列 CR LF(回车换行)或老式 Macintosh ASCII 字符 CR(回车)。无论在哪个平台上,这些形式都可以等价使用。输入结束也可以用作最终物理行的隐式终止符。

在嵌入 Python 时,将源码字符串传递给 Python API 时,应使用 C 标准惯例的换行符(\n),它代表 ASCII 字符 LF,作为行终止符。

三、注释

注释以井号(#)开头,并在物理行末尾截止。需要注意的是,井号不是字符串字面值。除非应用隐式行拼接规则,否则注释代表逻辑行的结束。语法解析器不会解析注释。

四、编码声明

当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 可识别的。 编码格式会被用于所有的词法分析,包括字符串字面值、注释和标识符等。

五、显式拼接行

两个及两个以上的物理行可用反斜杠(\)拼接为一个逻辑行,规则如下:

以不在字符串或注释内的反斜杠结尾时,物理行将与下一行拼接成一个逻辑行,并删除反斜杠及其后的换行符:

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

注意:以反斜杠结尾的行,不能加注释;反斜杠也不能拼接注释。除字符串字面值外,反斜杠不能拼接形符(如,除字符串字面值外,不能用反斜杠把形符切分至两个物理行)。反斜杠只能在代码的字符串字面值里,在其他任何位置都是非法的。

六、隐式拼接行

圆括号、方括号和花括号内的表达式可以分成多行书写,而无需使用反斜杠。例如:

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 字符。三引号字符串支持隐式拼接行,但不支持注释。

七、空白行

只包含空格符、制表符、换页符、注释的逻辑行会被忽略(即不生成 NEWLINE 形符)。交互模式输入语句时,空白行的处理方式可能因读取 – 求值 – 打印循环(REPL)的具体实现方式而不同。标准交互模式解释器中,完全空白的逻辑行(即连空格或注释都没有)将结束多行复合语句。

八、缩进

逻辑行开头的空白符(空格符和制表符)用于计算该行的缩进层级,以确定语句组块。制表符(从左至右)会被替换为一至八个空格,缩进空格的总数是八的倍数(与 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 的缩进无法匹配从栈里移除的缩进层级。)

九、形符间的空白字符

除非在逻辑行开头或字符串内,空格符、制表符、换页符等空白符都可以分隔形符。要把两个相连形符解读为不同形符,需要用空白符分隔(例如,ab 是一个形符,a b 则是两个形符)。

  • 广告合作

  • QQ群号:707632017

温馨提示:
1、本网站发布的内容(图片、视频和文字)以原创、转载和分享网络内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。邮箱:2942802716#qq.com(#改为@)。 2、本站原创内容未经允许不得转裁,转载请注明出处“站长百科”和原文地址。