python 全部缩进一行_Python(48)语言参考2:词法分析
生活随笔
收集整理的這篇文章主要介紹了
python 全部缩进一行_Python(48)语言参考2:词法分析
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
2.?詞法分析
Python 程序由一個(gè)?解析器?讀取。輸入到解析器的是一個(gè)由?詞法分析器?所生成的?形符?流,本章將描述詞法分析器是如何將一個(gè)文件拆分為一個(gè)個(gè)形符的。Python 會(huì)將讀取的程序文本轉(zhuǎn)為 Unicode 碼點(diǎn);源文件的文本編碼可由編碼聲明指定,默認(rèn)為 UTF-8,詳情見(jiàn)?PEP 3120。如果源文件無(wú)法被解碼,將會(huì)引發(fā)?SyntaxError。2.1.?行結(jié)構(gòu)
一個(gè) Python 程序可分為許多?邏輯行。2.1.1.?邏輯行
邏輯行的結(jié)束是以 NEWLINE 形符表示的。語(yǔ)句不能跨越邏輯行的邊界,除非其語(yǔ)法允許包含 NEWLINE (例如復(fù)合語(yǔ)句可由多行子語(yǔ)句組成)。一個(gè)邏輯行可由一個(gè)或多個(gè)?物理行?按照明確或隱含的?行拼接?規(guī)則構(gòu)成。2.1.2.?物理行
物理行是以一個(gè)行終止序列結(jié)束的字符序列。在源文件和字符串中,可以使用任何標(biāo)準(zhǔn)平臺(tái)上的行終止序列 - Unix 所用的 ASCII 字符 LF (換行), Windows 所用的 ASCII 字符序列 CR LF (回車加換行), 或者舊 Macintosh 所用的 ASCII 字符 CR (回車)。所有這些形式均可使用,無(wú)論具體平臺(tái)。輸入的結(jié)束也會(huì)被作為最后一個(gè)物理行的隱含終止標(biāo)志。當(dāng)嵌入 Python 時(shí),源碼字符串傳入 Python API 應(yīng)使用標(biāo)準(zhǔn) C 的傳統(tǒng)換行符 (即?\n,表示 ASCII 字符 LF 作為行終止標(biāo)志)。2.1.3.?注釋
一條注釋以不包含在字符串字面值內(nèi)的井號(hào) (#) 開頭,并在物理行的末尾結(jié)束。一條注釋標(biāo)志著邏輯行的結(jié)束,除非存在隱含的行拼接規(guī)則。注釋在語(yǔ)法分析中會(huì)被忽略。2.1.4.?編碼聲明
如果一條注釋位于 Python 腳本的第一或第二行,并且匹配正則表達(dá)式?coding[=:]\s*([-\w.]+),這條注釋會(huì)被作為編碼聲明來(lái)處理;上述表達(dá)式的第一組指定了源碼文件的編碼。編碼聲明必須獨(dú)占一行。如果它是在第二行,則第一行也必須是注釋。推薦的編碼聲明形式如下# -*- coding: -*-這也是 GNU Emacs 認(rèn)可的形式,以及# vim:fileencoding=這是 Bram Moolenaar 的 VIM 認(rèn)可的形式。如果沒(méi)有編碼聲明,則默認(rèn)編碼為 UTF-8。此外,如果文件的首字節(jié)為 UTF-8 字節(jié)順序標(biāo)志 (b'\xef\xbb\xbf'),文件編碼也聲明為 UTF-8 (這是 Microsoft 的?notepad?等軟件支持的形式)。編碼聲明指定的編碼名稱必須是 Python 所認(rèn)可的編碼。所有詞法分析將使用此編碼,包括語(yǔ)義字符串、注釋和標(biāo)識(shí)符。2.1.5.?顯式的行拼接
兩個(gè)或更多個(gè)物理行可使用反斜杠字符 (\) 拼接為一個(gè)邏輯行,規(guī)則如下: 當(dāng)一個(gè)物理行以一個(gè)不在字符串或注釋內(nèi)的反斜杠結(jié)尾時(shí),它將與下一行拼接構(gòu)成一個(gè)單獨(dú)的邏輯行,反斜杠及其后的換行符會(huì)被刪除。例如: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 datereturn 1以反斜杠結(jié)束的行不能帶有注釋。反斜杠不能用來(lái)拼接注釋。反斜杠不能用來(lái)拼接形符,字符串除外 (即原文字符串以外的形符不能用反斜杠分隔到兩個(gè)物理行)。不允許有原文字符串以外的反斜杠存在于物理行的其他位置。2.1.6.?隱式的行拼接
圓括號(hào)、方括號(hào)或花括號(hào)以內(nèi)的表達(dá)式允許分成多個(gè)物理行,無(wú)需使用反斜杠。例如: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ù)行的縮進(jìn)不影響程序結(jié)構(gòu)。后續(xù)行也允許為空白行。隱式拼接的行之間不會(huì)有 NEWLINE 形符。隱式拼接的行也可以出現(xiàn)于三引號(hào)字符串中 (見(jiàn)下);此情況下這些行不允許帶有注釋。2.1.7.?空白行
一個(gè)只包含空格符,制表符,進(jìn)紙符或者注釋的邏輯行會(huì)被忽略 (即不生成 NEWLINE 形符)。在交互模式輸入語(yǔ)句時(shí),對(duì)空白行的處理可能會(huì)因讀取-求值-打印循環(huán)的具體實(shí)現(xiàn)方式而存在差異。在標(biāo)準(zhǔn)交互模式解釋器中,一個(gè)完全空白的邏輯行 (即連空格或注釋都沒(méi)有) 將會(huì)結(jié)束一條多行復(fù)合語(yǔ)句。2.1.8.?縮進(jìn)
一個(gè)邏輯行開頭處的空白 (空格符和制表符) 被用來(lái)計(jì)算該行的縮進(jìn)等級(jí),以決定語(yǔ)句段落的組織結(jié)構(gòu)。制表符會(huì)被 (從左至右) 替換為一至八個(gè)空格,這樣縮進(jìn)的空格總數(shù)為八的倍數(shù) (這是為了與 Unix 所用的規(guī)則一致)。首個(gè)非空白字符之前的空格總數(shù)將確定該行的縮進(jìn)層次。一個(gè)縮進(jìn)不可使用反斜杠進(jìn)行多行拼接;首個(gè)反斜杠之前的空格將確定縮進(jìn)層次。在一個(gè)源文件中如果混合使用制表符和空格符縮進(jìn),并使得確定縮進(jìn)層次需要依賴于制表符對(duì)應(yīng)的空格數(shù)量設(shè)置,則被視為不合規(guī)則;此情況將會(huì)引發(fā)?TabError。跨平臺(tái)兼容性注釋:?由于非 UNIX 平臺(tái)上文本編輯器本身的特性,在一個(gè)源文件中混合使用制表符和空格符是不明智的。另外也要注意不同平臺(tái)還可能會(huì)顯式地限制最大縮進(jìn)層級(jí)。行首有時(shí)可能會(huì)有一個(gè)進(jìn)紙符;它在上述縮進(jìn)層級(jí)計(jì)算中會(huì)被忽略。處于行首空格內(nèi)其他位置的進(jìn)紙符的效果未定義 (例如它可能導(dǎo)致空格計(jì)數(shù)重置為零)。多個(gè)連續(xù)行各自的縮進(jìn)層級(jí)將會(huì)被放入一個(gè)堆棧用來(lái)生成 INDENT 和 DEDENT 形符,具體說(shuō)明如下。在讀取文件的第一行之前,先向堆棧推入一個(gè)零值;它將不再被彈出。被推入棧的層級(jí)數(shù)值從底至頂持續(xù)增加。每個(gè)邏輯行開頭的行縮進(jìn)層級(jí)將與棧頂行比較。如果相同,則不做處理。如果新行層級(jí)較高,則會(huì)被推入棧頂,并生成一個(gè) INDENT 形符。如果新行層級(jí)較低,則?應(yīng)當(dāng)?是棧中的層級(jí)數(shù)值之一;棧中高于該層級(jí)的所有數(shù)值都將被彈出,每彈出一級(jí)數(shù)值生成一個(gè) DEDENT 形符。在文件末尾,棧中剩余的每個(gè)大于零的數(shù)值生成一個(gè) DEDENT 形符。這是一個(gè)正確 (但令人迷惑) 的Python 代碼縮進(jìn)示例:def perm(l):# Compute the list of all permutations of lif 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以下示例顯示了各種縮進(jìn)錯(cuò)誤: def perm(l): # error: first line indentedfor i in range(len(l)): # error: not indented
s = l[:i] + l[i+1:]
p = perm(l[:i] + l[i+1:]) # error: unexpected indentfor x in p:
r.append(l[i:i+1] + x)return r # error: inconsistent dedent(實(shí)際上,前三個(gè)錯(cuò)誤會(huì)被解析器發(fā)現(xiàn);只有最后一個(gè)錯(cuò)誤是由詞法分析器發(fā)現(xiàn)的 ---?return?r?的縮進(jìn)無(wú)法匹配彈出棧的縮進(jìn)層級(jí)。)
2.1.9.?形符之間的空白
除非是在邏輯行的開頭或字符串內(nèi),空格符、制表符和進(jìn)紙符等空白符都同樣可以用來(lái)分隔形符。如果兩個(gè)形符彼此相連會(huì)被解析為一個(gè)不同的形符,則需要使用空白來(lái)分隔 (例如 ab 是一個(gè)形符,而 a b 是兩個(gè)形符)。2.2.?其他形符
除了 NEWLINE, INDENT 和 DEDENT,還存在以下類別的形符:?標(biāo)識(shí)符,?關(guān)鍵字,?字面值,?運(yùn)算符?以及?分隔符。空白字符 (之前討論過(guò)的行終止符除外) 不屬于形符,而是用來(lái)分隔形符。如果存在二義性,將從左至右讀取盡可能長(zhǎng)的合法字符串組成一個(gè)形符。2.3.?標(biāo)識(shí)符和關(guān)鍵字
標(biāo)識(shí)符 (或者叫做?名稱) 由以下詞法定義進(jìn)行描述。Python 中的標(biāo)識(shí)符語(yǔ)法是基于 Unicode 標(biāo)準(zhǔn)附件 UAX-31,并加入了下文所定義的細(xì)化與修改;更多細(xì)節(jié)還可參見(jiàn)?PEP 3131?。在 ASCII 范圍內(nèi) (U+0001..U+007F),可用于標(biāo)識(shí)符的字符與 Python 2.x 一致: 大寫和小寫字母?A?至?Z,下劃線?_?以及數(shù)字?0?至?9,但不可以數(shù)字打頭。Python 3.0 引入了 ASCII 范圍以外的額外字符 (見(jiàn)?PEP 3131)。這些字符的分類使用包含于?unicodedata?模塊中的 Unicode 字符數(shù)據(jù)庫(kù)版本。標(biāo)識(shí)符的長(zhǎng)度沒(méi)有限制。對(duì)大小寫敏感。identifier ::= xid_start xid_continue*id_start ::= id_continue ::= id_start, plus characters in the categories Mn, Mc, Nd, Pc and others with the Other_ID_Continue property>xid_start ::= id_start whose NFKC normalization is in "id_start xid_continue*">xid_continue ::= id_continue whose NFKC normalization is in "id_continue*">上文所用 Unicode 類別碼的含義:- Lu?- 大寫字母
- Ll?- 小寫字母
- Lt?- 詞首大寫字母
- Lm?- 修飾字母
- Lo?- 其他字母
- Nl?- 字母數(shù)字
- Mn?- 非空白標(biāo)識(shí)
- Mc?- 含空白標(biāo)識(shí)
- Nd?- 十進(jìn)制數(shù)字
- Pc?- 連接標(biāo)點(diǎn)
- Other_ID_Start?- 由?PropList.txt?定義的顯式字符列表,用來(lái)支持向下兼容
- Other_ID_Continue?- 同上
2.3.1.?關(guān)鍵字
以下標(biāo)識(shí)符被作為語(yǔ)言的保留字或稱?關(guān)鍵字,不可被用作普通標(biāo)識(shí)符。關(guān)鍵字的拼寫必須與這里列出的完全一致。False await else import passNone 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.?保留的標(biāo)識(shí)符類
某些標(biāo)識(shí)符類 (除了關(guān)鍵字) 具有特殊的含義。這些標(biāo)識(shí)符類的命名模式是以下劃線字符打頭和結(jié)尾:- _*
- 不會(huì)被?from?module?import?*?導(dǎo)入。特殊標(biāo)識(shí)符?_?在交互式解釋器中被用來(lái)存放最近一次求值結(jié)果;它保存在?builtins?模塊中。當(dāng)不處于交互模式時(shí),_?無(wú)特殊含義也沒(méi)有預(yù)定義。參見(jiàn)?import 語(yǔ)句。注解?_?作為名稱常用于連接國(guó)際化文本;請(qǐng)參看?gettext?模塊文檔了解有關(guān)此約定的詳情。
- __*__
- 系統(tǒng)定義的名稱,在非正式場(chǎng)合下被叫做 "dunder" 名稱。這些名稱是由解釋器及其實(shí)現(xiàn)(包括標(biāo)準(zhǔn)庫(kù))定義的。現(xiàn)有系統(tǒng)定義名稱相關(guān)的討論請(qǐng)參見(jiàn)?特殊方法名稱?等章節(jié)。未來(lái)的 Python 版本中還將定義更多此類名稱。任何情況下?任何?不遵循文檔所顯式指明的?__*__?名稱使用方式都可能導(dǎo)致無(wú)警告的錯(cuò)誤。
- __*
- 類的私有名稱。這種名稱在類定義中使用時(shí),會(huì)以一種混合形式重寫以避免在基類及派生類的 "私有" 屬性之間出現(xiàn)名稱沖突。參見(jiàn)?標(biāo)識(shí)符(名稱)。
2.4.?字面值
字面值用于表示一些內(nèi)置類型的常量。2.4.1.?字符串和字節(jié)串字面值
字符串字面值由以下詞法定義進(jìn)行描述: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 | stringescapeseqlongstringitem ::= longstringchar | stringescapeseqshortstringchar ::= longstringchar ::= stringescapeseq ::= "\" bytesliteral ::= bytesprefix(shortbytes | longbytes)bytesprefix ::= "b" | "B" | "br" | "Br" | "bR" | "BR" | "rb" | "rB" | "Rb" | "RB"shortbytes ::= "'" shortbytesitem* "'" | '"' shortbytesitem* '"'longbytes ::= "'''" longbytesitem* "'''" | '"""' longbytesitem* '"""'shortbytesitem ::= shortbyteschar | bytesescapeseqlongbytesitem ::= longbyteschar | bytesescapeseqshortbyteschar ::= longbyteschar ::= bytesescapeseq ::= "\" 這些條目中未提及的一個(gè)語(yǔ)法限制是?stringprefix?或?bytesprefix?與字面值的剩余部分之間不允許有空白。源字符集是由編碼聲明定義的;如果源文件中沒(méi)有編碼聲明則默認(rèn)為 UTF-8;參見(jiàn)?編碼聲明。自然語(yǔ)言描述: 兩種字面值都可以用成對(duì)單引號(hào) (') 或雙引號(hào) (") 來(lái)標(biāo)示首尾。它們也可以用成對(duì)的連續(xù)三個(gè)單引號(hào)或雙引號(hào)來(lái)標(biāo)示首尾 (這通常被稱為?三引號(hào)字符串)。反斜杠 (\) 字符被用來(lái)對(duì)特殊含義的字符進(jìn)行轉(zhuǎn)義,例如換行,反斜杠本身或是引號(hào)等字符。字節(jié)串字面值總是帶有前綴?'b'?或?'B';它們生成?bytes?類型而非?str?類型的實(shí)例。它們只能包含 ASCII 字符;字節(jié)對(duì)應(yīng)數(shù)值在128及以上必須以轉(zhuǎn)義形式來(lái)表示。字符串和字節(jié)串字面值都可以帶有前綴?'r'?或?'R';這種字符串被稱為?原始字符串?其中的反斜杠會(huì)被當(dāng)作其本身的字面字符來(lái)處理。因此在原始字符串字面值中,'\U'?和?'\u'?轉(zhuǎn)義形式不會(huì)被特殊對(duì)待。由于 Python 2.x 的原始統(tǒng)一碼字面值的特性與 Python 3.x 不一致,'ur'?語(yǔ)法已不再被支持。3.3 新版功能:?新加入了表示原始字節(jié)串的?'rb'?前綴,與?'br'?的意義相同。3.3 新版功能:?對(duì)舊式統(tǒng)一碼字面值 (u'value') 的支持被重新引入以簡(jiǎn)化 Python 2.x 和 3.x 代碼庫(kù)的同步維護(hù)。詳情見(jiàn)?PEP 414。包含?'f'?或?'F'?前綴的字符串字面值稱為?格式化字符串字面值;參見(jiàn)?格式化字符串字面值。'f'?可與?'r'?連用,但不能與?'b'?或?'u'?連用,因此存在原始格式化字符串,但不存在格式化字節(jié)串字面值。在三引號(hào)字面值中,允許存在未經(jīng)轉(zhuǎn)義的換行和引號(hào) (并原樣保留),除非是未經(jīng)轉(zhuǎn)義的連續(xù)三引號(hào),這標(biāo)示著字面值的結(jié)束。("引號(hào)" 是用來(lái)標(biāo)示字面值的字符,即?'?或?"。)除非帶有?'r'?或?'R'?前綴,字符串和字節(jié)串字面值中的轉(zhuǎn)義序列會(huì)基于類似標(biāo)準(zhǔn) C 中的轉(zhuǎn)義規(guī)則來(lái)解讀。可用的轉(zhuǎn)義序列如下:
| \newline | 反斜杠加換行全被忽略 | |
| \\ | 反斜杠 (\) | |
| \' | 單引號(hào) (') | |
| \" | 雙引號(hào) (") | |
| \a | ASCII 響鈴 (BEL) | |
| \b | ASCII 退格 (BS) | |
| \f | ASCII 進(jìn)紙 (FF) | |
| \n | ASCII 換行 (LF) | |
| \r | ASCII 回車 (CR) | |
| \t | ASCII 水平制表 (TAB) | |
| \v | ASCII 垂直制表 (VT) | |
| \ooo | 八進(jìn)制數(shù)?ooo?碼位的字符 | (1,3) |
| \xhh | 十六進(jìn)制數(shù)?hh?碼位的字符 | (2,3) |
| \N{name} | Unicode 數(shù)據(jù)庫(kù)中名稱為?name?的字符 | (4) |
| \uxxxx | 16位十六進(jìn)制數(shù)?xxxx?碼位的字符 | (5) |
| \Uxxxxxxxx | 32位16進(jìn)制數(shù)?xxxxxxxx?碼位的字符 | (6) |
2.4.2.?字符串字面值拼接
多個(gè)相鄰的字符串或字節(jié)串字面值 (以空白符分隔),所用的引號(hào)可以彼此不同,其含義等同于全部拼接為一體。因此,?"hello"?'world'?等同于?"helloworld"。此特性可以減少反斜杠的使用,以方便地將很長(zhǎng)的字符串分成多個(gè)物理行,甚至每部分字符串還可分別加注釋,例如:re.compile("[A-Za-z_]" # letter or underscore"[A-Za-z0-9_]*" # letter, digit or underscore)注意此特性是在句法層面定義的,但是在編譯時(shí)實(shí)現(xiàn)。在運(yùn)行時(shí)拼接字符串表達(dá)式必須使用 '+' 運(yùn)算符。還要注意字面值拼接時(shí)每個(gè)部分可以使用不同的引號(hào)風(fēng)格 (甚至混合使用原始字符串和三引號(hào)字符串),格式化字符串字面值也可與普通字符串字面值拼接。
2.4.3.?格式化字符串字面值
3.6 新版功能.格式化字符串字面值?或稱?f-string?是帶有?'f'?或?'F'?前綴的字符串字面值。這種字符串可包含替換字段,即以?{}?標(biāo)示的表達(dá)式。而其他字符串字面值總是一個(gè)常量,格式化字符串字面值實(shí)際上是會(huì)在運(yùn)行時(shí)被求值的表達(dá)式。轉(zhuǎn)義序列會(huì)像在普通字符串字面值中一樣被解碼 (除非字面值還被標(biāo)示為原始字符串)。解碼之后,字符串內(nèi)容所用的語(yǔ)法如下:f_string ::= (literal_char | "{{" | "}}" | replacement_field)*replacement_field ::= "{" f_expression ["="] ["!" conversion] [":" format_spec] "}"f_expression ::= (conditional_expression | "*" or_expr)("," conditional_expression | "," "*" or_expr)* [","]
| yield_expressionconversion ::= "s" | "r" | "a"format_spec ::= (literal_char | NULL | replacement_field)*literal_char ::= 字符串在花括號(hào)以外的部分按其字面值處理,除了雙重花括號(hào)?'{{'?或?'}}'?會(huì)被替換為相應(yīng)的單個(gè)花括號(hào)。單個(gè)左花括號(hào)?'{'?標(biāo)示一個(gè)替換字段,它以一個(gè) Python 表達(dá)式打頭。要同時(shí)顯示表達(dá)式文本及其求值后的結(jié)果值(這在調(diào)試時(shí)很有用),可以在表達(dá)式后加一個(gè)等于號(hào)?'='。之后可能帶有一個(gè)以嘆號(hào)?'!'?標(biāo)示的轉(zhuǎn)換字段。之后還可能帶有一個(gè)以冒號(hào)?':'?標(biāo)示的格式說(shuō)明符。替換字段以一個(gè)右花括號(hào)?'}'?作為結(jié)束。格式化字符串字面值中的表達(dá)式會(huì)被當(dāng)作包含在圓括號(hào)中的普通 Python 表達(dá)式一樣處理,但有少數(shù)例外。空表達(dá)式不被允許,lambda?和賦值表達(dá)式?:=?必須顯式地加上圓括號(hào)。替換表達(dá)式可以包含換行(例如在三重引號(hào)字符串中),但是不能包含注釋。每個(gè)表達(dá)式會(huì)在格式化字符串字面值所包含的位置按照從左至右的順序被求值。在 3.7 版更改:?在 Python 3.7 之前,?await?表達(dá)式包含?async?for?子句的推導(dǎo)式不允許在格式化字符串字面值表達(dá)式中使用,這是因?yàn)榫唧w實(shí)現(xiàn)存在一個(gè)問(wèn)題。在提供了等于號(hào)?'='?的時(shí)候,輸出將包含表達(dá)式文本,'='?以及求值結(jié)果。左花括號(hào)?'{'?之后包含在表達(dá)式中及?'='?后的空格將在輸出時(shí)被保留。默認(rèn)情況下,'='?會(huì)導(dǎo)致表達(dá)式的?repr()?被使用,除非專門指定了格式。當(dāng)指定了格式時(shí)默認(rèn)會(huì)使用表達(dá)式的?str(),除非聲明了轉(zhuǎn)換字段?'!r'。3.8 新版功能:?等號(hào)?'='。如果指定了轉(zhuǎn)換符,表達(dá)式的求值結(jié)果會(huì)先轉(zhuǎn)換再格式化。轉(zhuǎn)換符?'!s'?即對(duì)結(jié)果調(diào)用?str(),'!r'?為調(diào)用?repr(),而?'!a'?為調(diào)用?ascii()。在此之后結(jié)果會(huì)使用?format()?協(xié)議進(jìn)行格式化。格式說(shuō)明符會(huì)被傳入表達(dá)式或轉(zhuǎn)換結(jié)果的?__format__()?方法。如果省略格式說(shuō)明符則會(huì)傳入一個(gè)空字符串。然后格式化結(jié)果會(huì)包含在整個(gè)字符串最終的值當(dāng)中。頂層的格式說(shuō)明符可以包含有嵌套的替換字段。這些嵌套字段也可以包含有自己的轉(zhuǎn)換字段和?格式說(shuō)明符,但不可再包含更深層嵌套的替換字段。這里的?格式說(shuō)明符微型語(yǔ)言?與字符串 .format() 方法所使用的相同。格式化字符串字面值可以拼接,但是一個(gè)替換字段不能拆分到多個(gè)字面值。一些格式化字符串字面值的示例:>>> 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" '與正常字符串字面值采用相同語(yǔ)法導(dǎo)致的一個(gè)結(jié)果就是替換字段中的字符不能與外部的格式化字符串字面值所用的引號(hào)相沖突:f"abc {a["x"]} def" # error: outer string literal ended prematurelyf"abc {a['x']} def" # workaround: use different quoting格式表達(dá)式中不允許有反斜杠,這會(huì)引發(fā)錯(cuò)誤:f"newline: {ord('\n')}" # raises SyntaxError想包含需要用反斜杠轉(zhuǎn)義的值,可以創(chuàng)建一個(gè)臨時(shí)變量。>>> newline = ord('\n')>>> f"newline: {newline}"
'newline: 10'格式化字符串字面值不可用作文檔字符串,即便其中沒(méi)有包含表達(dá)式。>>> def foo():... f"Not a docstring"...>>> foo.__doc__ is None
True另請(qǐng)參見(jiàn)?PEP 498?了解加入格式化字符串字面值的提議,以及使用了相關(guān)的格式字符串機(jī)制的?str.format()。
2.4.4.?數(shù)字字面值
數(shù)字字面值有三種類型: 整型數(shù)、浮點(diǎn)數(shù)和虛數(shù)。沒(méi)有專門的復(fù)數(shù)字面值 (復(fù)數(shù)可由一個(gè)實(shí)數(shù)加一個(gè)虛數(shù)合成)。注意數(shù)字字面值并不包含正負(fù)號(hào);-1?這樣的負(fù)數(shù)實(shí)際上是由單目運(yùn)算符 '-' 和字面值?1?合成的。2.4.5.?整型數(shù)字面值
整型數(shù)字面值由以下詞法定義進(jìn)行描述:integer ::= decinteger | bininteger | octinteger | hexintegerdecinteger ::= 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ù)字面值的長(zhǎng)度沒(méi)有限制,能一直大到占滿可用內(nèi)存。在確定數(shù)字大小時(shí)字面值中的下劃線會(huì)被忽略。它們可用來(lái)將數(shù)碼分組以提高可讀性。一個(gè)下劃線可放在數(shù)碼之間,也可放在基數(shù)說(shuō)明符例如?0x?之后。注意非零的十進(jìn)制數(shù)開頭不允許有額外的零。這是為了避免與 Python 在版本 3.0 之前所使用的 C 風(fēng)格八進(jìn)制字面值相混淆。一些整型數(shù)字面值的示例如下:7 2147483647 0o177 0b1001101113 79228162514264337593543950336 0o377 0xdeadbeef100_000_000_000 0b_1110_0101在 3.6 版更改:?允許在字面值中使用下劃線進(jìn)行分組。2.4.6.?浮點(diǎn)數(shù)字面值
浮點(diǎn)數(shù)字面值由以下詞法定義進(jìn)行描述:floatnumber ::= pointfloat | exponentfloatpointfloat ::= [digitpart] fraction | digitpart "."exponentfloat ::= (digitpart | pointfloat) exponentdigitpart ::= digit (["_"] digit)*fraction ::= "." digitpartexponent ::= ("e" | "E") ["+" | "-"] digitpart注意整型數(shù)部分和指數(shù)部分在解析時(shí)總是以 10 為基數(shù)。例如,077e010?是合法的,且表示的數(shù)值與?77e10?相同。浮點(diǎn)數(shù)字面值允許的范圍依賴于具體實(shí)現(xiàn)。對(duì)于整型數(shù)字面值,支持以下劃線進(jìn)行分組。一些浮點(diǎn)數(shù)字面值的示例如下:3.14 10. .001 1e100 3.14e-10 0e0 3.14_15_93在 3.6 版更改:?允許在字面值中使用下劃線進(jìn)行分組。2.4.7.?虛數(shù)字面值
虛數(shù)字面值由以下詞法定義進(jìn)行描述:imagnumber ::= (floatnumber | digitpart) ("j" | "J")一個(gè)虛數(shù)字面值將生成一個(gè)實(shí)部為 0.0 的復(fù)數(shù)。復(fù)數(shù)是以一對(duì)浮點(diǎn)數(shù)來(lái)表示的,它們的取值范圍相同。要?jiǎng)?chuàng)建一個(gè)實(shí)部不為零的復(fù)數(shù),就加上一個(gè)浮點(diǎn)數(shù),例如?(3+4j)。一些虛數(shù)字面值的示例如下:3.14j 10.j 10j .001j 1e100j 3.14e-10j 3.14_15_93j2.5.?運(yùn)算符
以下形符屬于運(yùn)算符:+ - * ** / // % @<< >> & | ^ ~ :=
< > <= >= == !=
2.6.?分隔符
以下形符在語(yǔ)法中歸類為分隔符:( ) [ ] { }, : . ; @ = ->
+= -= *= /= //= %= @=
&= |= ^= >>= <<= **=句點(diǎn)也可出現(xiàn)于浮點(diǎn)數(shù)和虛數(shù)字面值中。連續(xù)三個(gè)句點(diǎn)有表示一個(gè)省略符的特殊含義。以上列表的后半部分為增強(qiáng)賦值操作符,在詞法中作為分隔符,但也起到運(yùn)算作用。以下可打印 ASCII 字符作為其他形符的組成部分時(shí)具有特殊含義,或是對(duì)詞法分析器有重要意義:' " # \以下可打印 ASCII 字符不在 Python 詞法中使用。如果出現(xiàn)于字符串字面值和注釋之外將無(wú)條件地引發(fā)錯(cuò)誤:$ ? `備注【1】http://www.unicode.org/Public/11.0.0/ucd/NameAliases.txt
總結(jié)
以上是生活随笔為你收集整理的python 全部缩进一行_Python(48)语言参考2:词法分析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 2345电脑管家_如何彻底清除流氓的23
- 下一篇: 离散数学 逻辑判断系统 代码_入学派位查