新聞中心
tokenize —- 對 python 代碼使用的標(biāo)記解析器
源碼: Lib/tokenize.py

鯉城網(wǎng)站建設(shè)公司創(chuàng)新互聯(lián),鯉城網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為鯉城千余家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站建設(shè)要多少錢,請找那個(gè)售后服務(wù)好的鯉城做網(wǎng)站的公司定做!
tokenize 模塊為 Python 源代碼提供了一個(gè)詞法掃描器,用 Python 實(shí)現(xiàn)。該模塊中的掃描器也將注釋作為標(biāo)記返回,這使得它對于實(shí)現(xiàn)“漂亮的輸出器”非常有用,包括用于屏幕顯示的著色器。
為了簡化標(biāo)記流的處理,所有的 運(yùn)算符 和 定界符 以及 Ellipsis 返回時(shí)都會(huì)打上通用的 OP 標(biāo)記。 可以通過 tokenize.tokenize() 返回的 named tuple 對象的 exact_type 屬性來獲得確切的標(biāo)記類型。
對輸入進(jìn)行解析標(biāo)記
主要的入口是一個(gè) generator:
tokenize.tokenize(readline)
生成器 tokenize() 需要一個(gè) readline 參數(shù),這個(gè)參數(shù)必須是一個(gè)可調(diào)用對象,且能提供與文件對象的 io.IOBase.readline() 方法相同的接口。每次調(diào)用這個(gè)函數(shù)都要 返回字節(jié)類型輸入的一行數(shù)據(jù)。
生成器產(chǎn)生 5 個(gè)具有這些成員的元組:令牌類型;令牌字符串;指定令牌在源中開始的行和列的 2 元組 (srow, scol) ;指定令牌在源中結(jié)束的行和列的 2 元組 (erow, ecol) ;以及發(fā)現(xiàn)令牌的行。所傳遞的行(最后一個(gè)元組項(xiàng))是 實(shí)際的 行。 5 個(gè)元組以 named tuple 的形式返回,字段名是: type string start end line 。
返回的 named tuple 有一個(gè)額外的屬性,名為 exact_type ,包含了 OP 標(biāo)記的確切操作符類型。 對于所有其他標(biāo)記類型, exact_type 等于命名元組的 type 字段。
在 3.1 版更改: 增加了對 named tuple 的支持。
在 3.3 版更改: 添加了對 exact_type 的支持。
根據(jù):pep:263 , tokenize() 通過尋找 UTF-8 BOM 或編碼 cookie 來確定文件的源編碼。
tokenize.generate_tokens(readline)
對讀取 unicode 字符串而不是字節(jié)的源進(jìn)行標(biāo)記。
和 tokenize() 一樣, readline 參數(shù)是一個(gè)返回單行輸入的可調(diào)用參數(shù)。然而, generate_tokens() 希望 readline 返回一個(gè) str 對象而不是字節(jié)。
其結(jié)果是一個(gè)產(chǎn)生具名元組的的迭代器,與 tokenize() 完全一樣。 它不會(huì)產(chǎn)生 ENCODING 標(biāo)記。
所有來自 token 模塊的常量也可從 tokenize 導(dǎo)出。
提供了另一個(gè)函數(shù)來逆轉(zhuǎn)標(biāo)記化過程。這對于創(chuàng)建對腳本進(jìn)行標(biāo)記、修改標(biāo)記流并寫回修改后腳本的工具很有用。
tokenize.untokenize(iterable)
將令牌轉(zhuǎn)換為 Python 源代碼。 iterable 必須返回至少有兩個(gè)元素的序列,即令牌類型和令牌字符串。任何額外的序列元素都會(huì)被忽略。
重構(gòu)的腳本以單個(gè)字符串的形式返回。 結(jié)果被保證為標(biāo)記回與輸入相匹配,因此轉(zhuǎn)換是無損的,并保證來回操作。 該保證只適用于標(biāo)記類型和標(biāo)記字符串,因?yàn)闃?biāo)記之間的間距(列位置)可能會(huì)改變。
它返回字節(jié),使用 ENCODING 標(biāo)記進(jìn)行編碼,這是由 tokenize() 輸出的第一個(gè)標(biāo)記序列。如果輸入中沒有編碼令牌,它將返回一個(gè)字符串。
tokenize() 需要檢測它所標(biāo)記源文件的編碼。它用來做這件事的函數(shù)是可用的:
tokenize.detect_encoding(readline)
detect_encoding() 函數(shù)用于檢測解碼 Python 源文件時(shí)應(yīng)使用的編碼。它需要一個(gè)參數(shù), readline ,與 tokenize() 生成器的使用方式相同。
它最多調(diào)用 readline 兩次,并返回所使用的編碼(作為一個(gè)字符串)和它所讀入的任何行(不是從字節(jié)解碼的)的 list 。
它從 UTF-8 BOM 或編碼 cookie 的存在中檢測編碼格式,如 PEP 263 所指明的。 如果 BOM 和 cookie 都存在,但不一致,將會(huì)引發(fā) SyntaxError。 請注意,如果找到 BOM ,將返回 'utf-8-sig' 作為編碼格式。
如果沒有指定編碼,那么將返回默認(rèn)的 'utf-8' 編碼.
使用 open() 來打開 Python 源文件:它使用 detect_encoding() 來檢測文件編碼。
tokenize.open(filename)
使用由 detect_encoding() 檢測到的編碼,以只讀模式打開一個(gè)文件。
3.2 新版功能.
exception tokenize.TokenError
當(dāng)文件中任何地方?jīng)]有完成 docstring 或可能被分割成幾行的表達(dá)式時(shí)觸發(fā),例如:
"""Beginning ofdocstring
或者:
[1,2,3
注意,未封閉的單引號(hào)字符串不會(huì)導(dǎo)致錯(cuò)誤發(fā)生。它們被標(biāo)記為 ERRORTOKEN ,然后是其內(nèi)容的標(biāo)記化。
命令行用法
3.3 新版功能.
tokenize 模塊可以作為一個(gè)腳本從命令行執(zhí)行。這很簡單:
python -m tokenize [-e] [filename.py]
可以接受以下選項(xiàng):
-h, —help
顯示此幫助信息并退出
-e, —exact
使用確切的類型顯示令牌名稱
如果 filename.py 被指定,其內(nèi)容會(huì)被標(biāo)記到 stdout 。否則,標(biāo)記化將在 stdin 上執(zhí)行。
例子
腳本改寫器的例子,它將 float 文本轉(zhuǎn)換為 Decimal 對象:
from tokenize import tokenize, untokenize, NUMBER, STRING, NAME, OPfrom io import BytesIOdef decistmt(s):"""Substitute Decimals for floats in a string of statements.>>> from decimal import Decimal>>> s = 'print(+21.3e-5*-.1234/81.7)'>>> decistmt(s)"print (+Decimal ('21.3e-5')*-Decimal ('.1234')/Decimal ('81.7'))"The format of the exponent is inherited from the platform C library.Known cases are "e-007" (Windows) and "e-07" (not Windows). Sincewe're only showing 12 digits, and the 13th isn't close to 5, therest of the output should be platform-independent.>>> exec(s) #doctest: +ELLIPSIS-3.21716034272e-0...7Output from calculations with Decimal should be identical across allplatforms.>>> exec(decistmt(s))-3.217160342717258261933904529E-7"""result = []g = tokenize(BytesIO(s.encode('utf-8')).readline) # tokenize the stringfor toknum, tokval, _, _, _ in g:if toknum == NUMBER and '.' in tokval: # replace NUMBER tokensresult.extend([(NAME, 'Decimal'),(OP, '('),(STRING, repr(tokval)),(OP, ')')])else:result.append((toknum, tokval))return untokenize(result).decode('utf-8')
從命令行進(jìn)行標(biāo)記化的例子。 腳本:
def say_hello():print("Hello, World!")say_hello()
將被標(biāo)記為以下輸出,其中第一列是發(fā)現(xiàn)標(biāo)記的行 / 列坐標(biāo)范圍,第二列是標(biāo)記的名稱,最后一列是標(biāo)記的值(如果有)。
$ python -m tokenize hello.py0,0-0,0: ENCODING 'utf-8'1,0-1,3: NAME 'def'1,4-1,13: NAME 'say_hello'1,13-1,14: OP '('1,14-1,15: OP ')'1,15-1,16: OP ':'1,16-1,17: NEWLINE '\n'2,0-2,4: INDENT ' '2,4-2,9: NAME 'print'2,9-2,10: OP '('2,10-2,25: STRING '"Hello, World!"'2,25-2,26: OP ')'2,26-2,27: NEWLINE '\n'3,0-3,1: NL '\n'4,0-4,0: DEDENT ''4,0-4,9: NAME 'say_hello'4,9-4,10: OP '('4,10-4,11: OP ')'4,11-4,12: NEWLINE '\n'5,0-5,0: ENDMARKER ''
可以使用 -e 選項(xiàng)來顯示確切的標(biāo)記類型名稱。
$ python -m tokenize -e hello.py0,0-0,0: ENCODING 'utf-8'1,0-1,3: NAME 'def'1,4-1,13: NAME 'say_hello'1,13-1,14: LPAR '('1,14-1,15: RPAR ')'1,15-1,16: COLON ':'1,16-1,17: NEWLINE '\n'2,0-2,4: INDENT ' '2,4-2,9: NAME 'print'2,9-2,10: LPAR '('2,10-2,25: STRING '"Hello, World!"'2,25-2,26: RPAR ')'2,26-2,27: NEWLINE '\n'3,0-3,1: NL '\n'4,0-4,0: DEDENT ''4,0-4,9: NAME 'say_hello'4,9-4,10: LPAR '('4,10-4,11: RPAR ')'4,11-4,12: NEWLINE '\n'5,0-5,0: ENDMARKER ''
以編程方式對文件進(jìn)行標(biāo)記的例子,用 generate_tokens() 讀取 unicode 字符串而不是字節(jié):
import tokenizewith tokenize.open('hello.py') as f:tokens = tokenize.generate_tokens(f.readline)for token in tokens:print(token)
或者通過 tokenize() 直接讀取字節(jié)數(shù)據(jù):
import tokenizewith open('hello.py', 'rb') as f:tokens = tokenize.tokenize(f.readline)for token in tokens:print(token)
名稱欄目:創(chuàng)新互聯(lián)Python教程:tokenize—-對Python代碼使用的標(biāo)記解析器
本文來源:http://m.5511xx.com/article/dphdeic.html


咨詢
建站咨詢
