2. 詞法分析?
Python 程序由 解析器 讀取,輸入解析器的是 詞法分析器 生成的 形符 流。本章介紹詞法分析器怎樣把文件拆成形符。
Python 將讀取的程序文本轉為 Unicode 代碼點;編碼聲明用于指定源文件的編碼,默認為 UTF-8,詳見 PEP 3120。源文件不能解碼時,觸發(fā) SyntaxError
。
2.1. 行結構?
Python 程序可以拆分為多個 邏輯行。
2.1.1. 邏輯行?
NEWLINE 形符表示結束邏輯行。語句不能超出邏輯行的邊界,除非句法支持 NEWLINE (例如,復合語句中的多行子語句)。根據顯式或隱式 行拼接 規(guī)則,一個或多個 物理行 可組成邏輯行。
2.1.2. 物理行?
物理行是一序列字符,由行尾序列終止。源文件和字符串可使用任意標準平臺行終止序列 - Unix ASCII 字符 LF (換行)、 Windows ASCII 字符序列 CR LF (回車換行)、或老式 Macintosh ASCII 字符 CR (回車)。不管在哪個平臺,這些形式均可等價使用。輸入結束也可以用作最終物理行的隱式終止符。
嵌入 Python 時,傳入 Python API 的源碼字符串應使用 C 標準慣例換行符(\n
,代表 ASCII 字符 LF, 行終止符)。
2.1.4. 編碼聲明?
Python 腳本第一或第二行的注釋匹配正則表達式 coding[=:]\s*([-\w.]+)
時,該注釋會被當作編碼聲明;這個表達式的第一組指定了源碼文件的編碼。編碼聲明必須獨占一行,在第二行時,則第一行必須也是注釋。編碼表達式的形式如下:
# -*- coding: <encoding-name> -*-
這也是 GNU Emacs 認可的形式,此外,還支持如下形式:
# vim:fileencoding=<encoding-name>
這是 Bram Moolenaar 的 VIM 認可的形式。
沒有編碼聲明時,默認編碼為 UTF-8。此外,如果文件的首字節(jié)為 UTF-8 字節(jié)順序標志(b'\xef\xbb\xbf'
),文件編碼也聲明為 UTF-8(這是 Microsoft 的 notepad 等軟件支持的形式)。
If an encoding is declared, the encoding name must be recognized by Python (see 標準編碼). The encoding is used for all lexical analysis, including string literals, comments and identifiers.
2.1.5. 顯式拼接行?
兩個及兩個以上的物理行可用反斜杠(\
)拼接為一個邏輯行,規(guī)則如下:以不在字符串或注釋內的反斜杠結尾時,物理行將與下一行拼接成一個邏輯行,并刪除反斜杠及其后的換行符。例如:
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
隱式行拼接可含注釋;后續(xù)行的縮進并不重要;還支持空的后續(xù)行。隱式拼接行之間沒有 NEWLINE 形符。三引號字符串支持隱式拼接行(見下文),但不支持注釋。
2.1.7. 空白行?
只包含空格符、制表符、換頁符、注釋的邏輯行會被忽略(即不生成 NEWLINE 形符)。交互模式輸入語句時,空白行的處理方式可能因讀取 - 求值 - 打印循環(huán)(REPL)的具體實現(xiàn)方式而不同。標準交互模式解釋器中,完全空白的邏輯行(即連空格或注釋都沒有)將結束多行復合語句。
2.1.8. 縮進?
邏輯行開頭的空白符(空格符和制表符)用于計算該行的縮進層級,決定語句組塊。
制表符(從左至右)被替換為一至八個空格,縮進空格的總數(shù)是八的倍數(shù)(與 Unix 的規(guī)則保持一致)。首個非空字符前的空格數(shù)決定了該行的縮進層次??s進不能用反斜杠進行多行拼接;首個反斜杠之前的空白符決定了縮進的層次。
源文件混用制表符和空格符縮進時,因空格數(shù)量與制表符相關,由此產生的不一致將導致不能正常識別縮進層次,從而觸發(fā) TabError
。
跨平臺兼容性說明: 鑒于非 UNIX 平臺文本編輯器本身的特性,請勿在源文件中混用制表符和空格符。另外也請注意,不同平臺有可能會顯式限制最大縮進層級。
行首含換頁符時,縮進計算將忽略該換頁符。換頁符在行首空白符內其他位置的效果未定義(例如,可能導致空格計數(shù)重置為零)。
連續(xù)行的縮進層級以堆棧形式生成 INDENT 和 DEDENT 形符,說明如下。
讀取文件第一行前,先向棧推入一個零值,該零值不會被移除。推入棧的層級值從底至頂持續(xù)增加。每個邏輯行開頭的行縮進層級將與棧頂行比較。如果相等,則不做處理。如果新行層級較高,則會被推入棧頂,并生成一個 INDENT 形符。如果新行層級較低,則 應當 是棧中的層級數(shù)值之一;棧中高于該層級的所有數(shù)值都將被移除,每移除一級數(shù)值生成一個 DEDENT 形符。文件末尾,棧中剩余的每個大于零的數(shù)值生成一個 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 則是兩個形符)。
2.2. 其他形符?
除 NEWLINE、INDENT、DEDENT 外,還有 標識符、關鍵字、字面值、運算符 、分隔符 等形符。 空白符(前述的行終止符除外)不是形符,可用于分隔形符。存在二義性時,將從左至右,讀取盡量長的字符串組成合法形符。
2.3. 標識符和關鍵字?
標識符(也稱為 名稱)的詞法定義說明如下。
Python 標識符的句法基于 Unicode 標準附件 UAX-31,并加入了下文定義的細化與修改;詳見 PEP 3131 。
與 Python 2.x 一樣,在 ASCII 范圍內(U+0001..U+007F),有效標識符字符為: 大小寫字母 A
至 Z
、下劃線 _
、數(shù)字 0
至 9
,但不能以數(shù)字開頭。
Python 3.0 引入了 ASCII 之外的更多字符(請參閱 PEP 3131)。這些字符的分類使用 unicodedata
模塊中的 Unicode 字符數(shù)據庫版本。
標識符的長度沒有限制,但區(qū)分大小寫。
identifier ::=xid_start
xid_continue
* id_start ::= <all characters in general categories Lu, Ll, Lt, Lm, Lo, Nl, the underscore, and characters with the Other_ID_Start property> id_continue ::= <all characters inid_start
, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property> xid_start ::= <all characters inid_start
whose NFKC normalization is in "id_start xid_continue*"> xid_continue ::= <all characters inid_continue
whose NFKC normalization is in "id_continue*">
上述 Unicode 類別碼的含義:
Lu - 大寫字母
Ll - 小寫字母
Lt - 詞首大寫字母
Lm - 修飾符字母
Lo - 其他字母
Nl - 字母數(shù)字
Mn - 非空白標識
Mc - 含空白標識
Nd - 十進制數(shù)字
Pc - 連接標點
Other_ID_Start - explicit list of characters in PropList.txt to support backwards compatibility
Other_ID_Continue - 同上
在解析時,所有標識符都會被轉換為規(guī)范形式 NFKC;標識符的比較都是基于 NFKC。
A non-normative HTML file listing all valid identifier characters for Unicode 14.0.0 can be found at https://www.unicode.org/Public/14.0.0/ucd/DerivedCoreProperties.txt
2.3.1. 關鍵字?
以下標識符為保留字,或稱 關鍵字,不可用于普通標識符。關鍵字的拼寫必須與這里列出的完全一致:
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
2.3.2. 軟關鍵字?
3.10 新版功能.
某些標識符僅在特定上下文中被保留。 它們被稱為 軟關鍵字。 match
, case
和 _
等標識符在模式匹配語句相關的上下文中具有相當于關鍵字的語義,但這種區(qū)分是在解析器層級完成,而不是在形符化的時候。
作為軟關鍵字,它們能夠與模式匹配一起使用,同時仍然保持與使用 match
, case
和 _
作為標識符名稱的現(xiàn)有代碼的兼容性。
2.3.3. 保留的標識符類?
某些標識符類(除了關鍵字)具有特殊含義。這些類的命名模式以下劃線字符開頭,并以下劃線結尾:
_*
Not imported by
from module import *
._
In a
case
pattern within amatch
statement,_
is a soft keyword that denotes a wildcard.Separately, the interactive interpreter makes the result of the last evaluation available in the variable
_
. (It is stored in thebuiltins
module, alongside built-in functions likeprint
.)Elsewhere,
_
is a regular identifier. It is often used to name "special" items, but it is not special to Python itself.__*__
系統(tǒng)定義的名稱,通常簡稱為 "dunder" 。這些名稱由解釋器及其實現(xiàn)(包括標準庫)定義。現(xiàn)有系統(tǒng)定義名稱相關的論述詳見 特殊方法名稱 等章節(jié)。Python 未來版本中還將定義更多此類名稱。任何情況下,任何 不顯式遵從
__*__
名稱的文檔用法,都可能導致無警告提示的錯誤。__*
類的私有名稱。類定義時,此類名稱以一種混合形式重寫,以避免基類及派生類的 "私有" 屬性之間產生名稱沖突。詳見 標識符(名稱)。
2.4. 字面值?
字面值是內置類型常量值的表示法。
2.4.1. 字符串與字節(jié)串字面值?
字符串字面值的詞法定義如下:
stringliteral ::= [stringprefix
](shortstring
|longstring
) stringprefix ::= "r" | "u" | "R" | "U" | "f" | "F" | "fr" | "Fr" | "fR" | "FR" | "rf" | "rF" | "Rf" | "RF" shortstring ::= "'"shortstringitem
* "'" | '"'shortstringitem
* '"' longstring ::= "'''"longstringitem
* "'''" | '"""'longstringitem
* '"""' shortstringitem ::=shortstringchar
|stringescapeseq
longstringitem ::=longstringchar
|stringescapeseq
shortstringchar ::= <any source character except "\" or newline or the quote> longstringchar ::= <any source character except "\"> stringescapeseq ::= "\" <any source character>
bytesliteral ::=bytesprefix
(shortbytes
|longbytes
) bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB" shortbytes ::= "'"shortbytesitem
* "'" | '"'shortbytesitem
* '"' longbytes ::= "'''"longbytesitem
* "'''" | '"""'longbytesitem
* '"""' shortbytesitem ::=shortbyteschar
|bytesescapeseq
longbytesitem ::=longbyteschar
|bytesescapeseq
shortbyteschar ::= <any ASCII character except "\" or newline or the quote> longbyteschar ::= <any ASCII character except "\"> bytesescapeseq ::= "\" <any ASCII character>
One syntactic restriction not indicated by these productions is that whitespace
is not allowed between the stringprefix
or
bytesprefix
and the rest of the literal. The source
character set is defined by the encoding declaration; it is UTF-8 if no encoding
declaration is given in the source file; see section 編碼聲明.
In plain English: Both types of literals can be enclosed in matching single quotes
('
) or double quotes ("
). They can also be enclosed in matching groups
of three single or double quotes (these are generally referred to as
triple-quoted strings). The backslash (\
) character is used to give special
meaning to otherwise ordinary characters like n
, which means 'newline' when
escaped (\n
). It can also be used to escape characters that otherwise have a
special meaning, such as newline, backslash itself, or the quote character.
See escape sequences below for examples.
字節(jié)串字面值要加前綴 'b'
或 'B'
;生成的是類型 bytes
的實例,不是類型 str
的實例;字節(jié)串只能包含 ASCII 字符;字節(jié)串數(shù)值大于等于 128 時,必須用轉義表示。
字符串和字節(jié)串都可以加前綴 'r'
或 'R'
,稱為 原始字符串,原始字符串把反斜杠當作原義字符,不執(zhí)行轉義操作。因此,原始字符串不轉義 '\U'
和 '\u'
。與 Python 2.x 的原始 unicode 字面值操作不同,Python 3.x 現(xiàn)已不支持 'ur'
句法。
3.3 新版功能: 新增原始字節(jié)串 'rb'
前綴,是 'br'
的同義詞。
3.3 新版功能: 支持 unicode 字面值(u'value'
)遺留代碼,簡化 Python 2.x 和 3.x 并行代碼庫的維護工作。詳見 PEP 414。
前綴為 'f'
或 'F'
的字符串稱為 格式字符串;詳見 格式字符串字面值。'f'
可與 'r'
連用,但不能與 'b'
或 'u'
連用,因此,可以使用原始格式字符串,但不能使用格式字節(jié)串字面值。
三引號字面值可以包含未轉義的換行和引號(原樣保留),除了連在一起的,用于終止字面值的,未經轉義的三個引號。("引號" 是啟用字面值的字符,可以是 '
,也可以是 "
。)
如未標注 'r'
或 'R'
前綴,字符串和字節(jié)串字面值中,轉義序列以類似 C 標準的規(guī)則進行解釋??捎玫霓D義序列如下:
轉義序列 |
含意 |
備注 |
---|---|---|
|
忽略反斜杠與換行符 |
|
|
反斜杠( |
|
|
單引號( |
|
|
雙引號( |
|
|
ASCII 響鈴(BEL) |
|
|
ASCII 退格符(BS) |
|
|
ASCII 換頁符(FF) |
|
|
ASCII 換行符(LF) |
|
|
ASCII 回車符(CR) |
|
|
ASCII 水平制表符(TAB) |
|
|
ASCII 垂直制表符(VT) |
|
|
八進制數(shù) ooo 字符 |
(1,3) |
|
十六進制數(shù) hh 字符 |
(2,3) |
字符串字面值專用的轉義序列:
轉義序列 |
含意 |
備注 |
---|---|---|
|
Unicode 數(shù)據庫中名為 name 的字符 |
(4) |
|
16 位十六進制數(shù) xxxx 碼位的字符 |
(5) |
|
32 位 16 進制數(shù) xxxxxxxx 碼位的字符 |
(6) |
注釋:
與 C 標準一致,接受最多三個八進制數(shù)字。
在 3.11 版更改: Octal escapes with value larger than
0o377
produce aDeprecationWarning
. In a future Python version they will be aSyntaxWarning
and eventually aSyntaxError
.與 C 標準不同,必須為兩個十六進制數(shù)字。
字節(jié)串 字面值中,十六進制數(shù)和八進制數(shù)的轉義碼以相應數(shù)值代表每個字節(jié)。字符串 字面值中,這些轉義碼以相應數(shù)值代表每個 Unicode 字符。
在 3.3 版更改: 加入了對別名 1 的支持。
必須為 4 個十六進制數(shù)碼。
表示任意 Unicode 字符。必須為 8 個十六進制數(shù)碼。
與 C 標準不同,無法識別的轉義序列在字符串里原樣保留,即,輸出結果保留反斜杠。(調試時,這種方式很有用:輸錯轉義序列時,更容易在輸出結果中識別錯誤。)注意,在字節(jié)串字面值內,字符串字面值專用的轉義序列屬于無法識別的轉義序列。
在 3.6 版更改: 無法識別的轉義序列觸發(fā)
DeprecationWarning
。未來的 Python 發(fā)行版將改為觸發(fā)SyntaxWarning
,最終會改為觸發(fā)SyntaxError
。
即使在原始字面值中,引號也可以用反斜杠轉義,但反斜杠會保留在輸出結果里;例如 r"\""
是由兩個字符組成的有效字符串字面值:反斜杠和雙引號;r"\"
則不是有效字符串字面值(原始字符串也不能以奇數(shù)個反斜杠結尾)。尤其是,原始字面值不能以單個反斜杠結尾 (反斜杠會轉義其后的引號)。還要注意,反斜杠加換行在字面值中被解釋為兩個字符,而 不是 連續(xù)行。
2.4.2. 字符串字面值合并?
以空白符分隔的多個相鄰字符串或字節(jié)串字面值,可用不同引號標注,等同于合并操作。因此,"hello" 'world'
等價于 "helloworld"
。此功能不需要反斜杠,即可將長字符串分為多個物理行,還可以為不同部分的字符串添加注釋,例如:
re.compile("[A-Za-z_]" # letter or underscore
"[A-Za-z0-9_]*" # letter, digit or underscore
)
注意,此功能在句法層面定義,在編譯時實現(xiàn)。在運行時,合并字符串表達式必須使用 '+' 運算符。還要注意,字面值合并可以為每個部分應用不同的引號風格(甚至混用原始字符串和三引號字符串),格式字符串字面值也可以與純字符串字面值合并。
2.4.3. 格式字符串字面值?
3.6 新版功能.
格式字符串字面值 或稱 f-string 是標注了 'f'
或 'F'
前綴的字符串字面值。這種字符串可包含替換字段,即以 {}
標注的表達式。其他字符串字面值只是常量,格式字符串字面值則是可在運行時求值的表達式。
除非字面值標記為原始字符串,否則,與在普通字符串字面值中一樣,轉義序列也會被解碼。解碼后,用于字符串內容的語法如下:
f_string ::= (literal_char
| "{{" | "}}" |replacement_field
)* replacement_field ::= "{"f_expression
["="] ["!"conversion
] [":"format_spec
] "}" f_expression ::= (conditional_expression
| "*"or_expr
) (","conditional_expression
| "," "*"or_expr
)* [","] |yield_expression
conversion ::= "s" | "r" | "a" format_spec ::= (literal_char
| NULL |replacement_field
)* literal_char ::= <any code point except "{", "}" or NULL>
雙花括號 '{{'
或 '}}'
被替換為單花括號,花括號外的字符串仍按字面值處理。單左花括號 '{'
標記以 Python 表達式開頭的替換字段。在表達式后加等于號 '='
,可在求值后,同時顯示表達式文本及其結果(用于調試)。 隨后是用嘆號 '!'
標記的轉換字段。還可以在冒號 ':'
后附加格式說明符。替換字段以右花括號 '}'
為結尾。
格式字符串字面值中,表達式的處理與圓括號中的常規(guī) Python 表達式基本一樣,但也有一些不同的地方。不允許使用空表達式;lambda
和賦值表達式 :=
必須顯式用圓括號標注;替換表達式可以包含換行(例如,三引號字符串中),但不能包含注釋;在格式字符串字面值語境內,按從左至右的順序,為每個表達式求值。
表達式里含等號 '='
時,輸出內容包括表達式文本、'='
、求值結果。輸出內容可以保留表達式中左花括號 '{'
后,及 '='
后的空格。沒有指定格式時,'='
默認調用表達式的 repr()
。指定了格式時,默認調用表達式的 str()
,除非聲明了轉換字段 '!r'
。
3.8 新版功能: 等號 '='
。
指定了轉換符時,表達式求值的結果會先轉換,再格式化。轉換符 '!s'
調用 str()
轉換求值結果,'!r'
調用 repr()
,'!a'
調用 ascii()
。
輸出結果的格式化使用 format()
協(xié)議。格式說明符傳入表達式或轉換結果的 __format__()
方法。省略格式說明符,則傳入空字符串。然后,格式化結果包含在整個字符串的最終值里。
頂層格式說明符可以包含嵌套替換字段。嵌套字段也可以包含自己的轉換字段和 格式說明符,但不可再包含更深層嵌套的替換字段。格式說明符微語言 與 str.format()
方法使用的微語言相同。
格式化字符串字面值可以拼接,但是一個替換字段不能拆分到多個字面值。
格式字符串字面值示例如下:
>>> name = "Fred"
>>> f"He said his name is {name!r}."
"He said his name is 'Fred'."
>>> f"He said his name is {repr(name)}." # repr() is equivalent to !r
"He said his name is 'Fred'."
>>> width = 10
>>> precision = 4
>>> value = decimal.Decimal("12.34567")
>>> f"result: {value:{width}.{precision}}" # nested fields
'result: 12.35'
>>> today = datetime(year=2017, month=1, day=27)
>>> f"{today:%B %d, %Y}" # using date format specifier
'January 27, 2017'
>>> f"{today=:%B %d, %Y}" # using date format specifier and debugging
'today=January 27, 2017'
>>> number = 1024
>>> f"{number:#0x}" # using integer format specifier
'0x400'
>>> foo = "bar"
>>> f"{ foo = }" # preserves whitespace
" foo = 'bar'"
>>> line = "The mill's closed"
>>> f"{line = }"
'line = "The mill\'s closed"'
>>> f"{line = :20}"
"line = The mill's closed "
>>> f"{line = !r:20}"
'line = "The mill\'s closed" '
與常規(guī)字符串字面值的語法一樣,替換字段中的字符不能與外層格式字符串字面值的引號沖突:
f"abc {a["x"]} def" # error: outer string literal ended prematurely
f"abc {a['x']} def" # workaround: use different quoting
格式表達式中不能有反斜杠,否則會報錯:
f"newline: {ord('\n')}" # raises SyntaxError
要使用反斜杠轉義的值,則需創(chuàng)建臨時變量。
>>> newline = ord('\n')
>>> f"newline: {newline}"
'newline: 10'
即便未包含表達式,格式字符串字面值也不能用作文檔字符串。
>>> def foo():
... f"Not a docstring"
...
>>> foo.__doc__ is None
True
參閱 PEP 498,了解格式字符串字面值的提案,以及與格式字符串機制相關的 str.format()
。
2.4.4. 數(shù)值字面值?
數(shù)值字面值有三種類型:整數(shù)、浮點數(shù)、虛數(shù)。沒有復數(shù)字面值(復數(shù)由實數(shù)加虛數(shù)構成)。
注意,數(shù)值字面值不含正負號;實際上,-1
等負數(shù)是由一元運算符 '-
' 和字面值 1
合成的。
2.4.5. 整數(shù)字面值?
整數(shù)字面值詞法定義如下:
integer ::=decinteger
|bininteger
|octinteger
|hexinteger
decinteger ::=nonzerodigit
(["_"]digit
)* | "0"+ (["_"] "0")* bininteger ::= "0" ("b" | "B") (["_"]bindigit
)+ octinteger ::= "0" ("o" | "O") (["_"]octdigit
)+ hexinteger ::= "0" ("x" | "X") (["_"]hexdigit
)+ nonzerodigit ::= "1"..."9" digit ::= "0"..."9" bindigit ::= "0" | "1" octdigit ::= "0"..."7" hexdigit ::=digit
| "a"..."f" | "A"..."F"
整數(shù)字面值的長度沒有限制,能一直大到占滿可用內存。
確定數(shù)值時,會忽略字面值中的下劃線。下劃線只是為了分組數(shù)字,讓數(shù)字更易讀。下劃線可在數(shù)字之間,也可在 0x
等基數(shù)說明符后。
注意,除了 0 以外,十進制數(shù)字的開頭不允許有零。以免與 Python 3.0 版之前使用的 C 樣式八進制字面值混淆。
整數(shù)字面值示例如下:
7 2147483647 0o177 0b100110111
3 79228162514264337593543950336 0o377 0xdeadbeef
100_000_000_000 0b_1110_0101
在 3.6 版更改: 現(xiàn)已支持在字面值中,用下劃線分組數(shù)字。
2.4.6. 浮點數(shù)字面值?
浮點數(shù)字面值詞法定義如下:
floatnumber ::=pointfloat
|exponentfloat
pointfloat ::= [digitpart
]fraction
|digitpart
"." exponentfloat ::= (digitpart
|pointfloat
)exponent
digitpart ::=digit
(["_"]digit
)* fraction ::= "."digitpart
exponent ::= ("e" | "E") ["+" | "-"]digitpart
注意,解析時,整數(shù)和指數(shù)部分總以 10 為基數(shù)。例如,077e010
是合法的,表示的數(shù)值與 77e10
相同。浮點數(shù)字面值的支持范圍取決于具體實現(xiàn)。整數(shù)字面值支持用下劃線分組數(shù)字。
浮點數(shù)字面值示例如下:
3.14 10. .001 1e100 3.14e-10 0e0 3.14_15_93
在 3.6 版更改: 現(xiàn)已支持在字面值中,用下劃線分組數(shù)字。
2.4.7. 虛數(shù)字面值?
虛數(shù)字面值詞法定義如下:
imagnumber ::= (floatnumber
|digitpart
) ("j" | "J")
虛數(shù)字面值生成實部為 0.0 的復數(shù)。復數(shù)由一對浮點數(shù)表示,它們的取值范圍相同。創(chuàng)建實部不為零的復數(shù),則需添加浮點數(shù),例如 (3+4j)
。虛數(shù)字面值示例如下:
3.14j 10.j 10j .001j 1e100j 3.14e-10j 3.14_15_93j
2.5. 運算符?
運算符如下所示:
+ - * ** / // % @
<< >> & | ^ ~ :=
< > <= >= == !=
2.6. 分隔符?
以下形符在語法中為分隔符:
( ) [ ] { }
, : . ; @ = ->
+= -= *= /= //= %= @=
&= |= ^= >>= <<= **=
句點也可以用于浮點數(shù)和虛數(shù)字面值。三個連續(xù)句點表示省略符。列表后半部分是增強賦值操作符,用作詞法分隔符,但也可以執(zhí)行運算。
以下 ASCII 字符具有特殊含義,對詞法分析器有重要意義:
' " # \
以下 ASCII 字符不用于 Python。在字符串字面值或注釋外使用時,將直接報錯:
$ ? `
備注
2.1.3. 注釋?
注釋以井號 (
#
) 開頭,在物理行末尾截止。注意,井號不是字符串字面值。除非應用隱式行拼接規(guī)則,否則,注釋代表邏輯行結束。句法不解析注釋。