On this page
32.7. tokenize —用于 Python 的 Tokenizer 源
源代码: Lib/tokenize.py
tokenize模块为 Python 源代码提供了词法扫描器,该词法扫描器以 Python 实现。该模块中的扫描仪也以令牌的形式返回 Comments,这对于实现“漂亮打印机”(包括用于屏幕显示的着色器)非常有用。
为了简化令牌流的处理,使用通用的token.OP令牌类型返回所有Operators和Delimiters令牌。可以pass检查从tokenize.generate_tokens()返回的 Tuples 的第二个字段(包含匹配的实际令牌字符串)来确定标识特定操作员令牌的字符序列,从而确定确切的类型。
主要入口点是generator:
tokenize.
generate_tokens
(* readline *)- generate_tokens()生成器需要一个参数* readline ,该参数必须是可调用的对象,该对象提供与内置文件对象的readline()方法相同的接口(请参见File Objects)。每次对函数的调用都应以字符串形式返回一行 Importing。另外, readline *可以是可调用的对象,它pass提高StopIteration来表示完成。
生成器生成具有以下成员的 5Tuples:令牌类型;令牌字符串; 2 个 Tuples 的(srow, scol)
int,用于指定源中令牌开始的行和列; 2 元整数(erow, ecol)
int,用于指定令牌在源中结束的行和列;以及找到令牌的行。传递的行(最后一个 Tuples 项)是逻辑行;包括续行。
2.2 版中的新Function。
保留了较旧的入口点以实现向后兼容性:
tokenize.
tokenize
(* readline * [,* tokeneater *])- tokenize()函数接受两个参数:一个代表 Importing 流,另一个为tokenize()提供输出机制。
第一个参数* readline 必须是可调用对象,该对象提供与内置文件对象的readline()方法相同的接口(请参见File Objects)。每次对函数的调用都应以字符串形式返回一行 Importing。或者, readline *可以是可调用的对象,它pass提高StopIteration来表示 signal 完成。
在版本 2.5 中进行了更改:添加了StopIteration支持。
第二个参数* tokeneater *也必须是可调用对象。每个令牌都调用一次,带有五个参数,分别对应于generate_tokens()生成的 Tuples。
token模块中的所有常量也都从tokenize中导出,另外两个可能由tokenize()传递给* tokeneater *函数的令牌类型值也是如此:
tokenize.
COMMENT
- 用于指示 Comment 的令牌值。
tokenize.
NL
- 用于指示非终止换行符的令牌值。 NEWLINE 令牌指示 Python 代码的逻辑行的结尾;当逻辑代码行在多个物理行上连续时,会生成 NL 令牌。
提供了另一个Function来逆转令牌化过程。这对于创建标记脚本脚本,修改标记流以及写回修改后脚本的工具很有用。
tokenize.
untokenize
(可迭代)- 将令牌转换回 Python 源代码。 * iterable *必须返回至少包含两个元素的序列:令牌类型和令牌字符串。任何其他序列元素都将被忽略。
重建的脚本作为单个字符串返回。保证结果可以令牌化回去以匹配 Importing,从而使转换无损并确保往返。由于令牌之间的间距(列位置)可能会更改,因此该保证仅适用于令牌类型和令牌字符串。
2.5 版的新Function。
- exception
tokenize.
TokenError
- 当文档字符串或表达式可能会分成几行时,在文件中的任何位置未完成时引发,例如:
"""Beginning of
docstring
or:
[1,
2,
3
请注意,未封闭的单引号字符串不会引起错误。它们被标记为ERRORTOKEN
,随后是其内容的标记。
将浮点 Literals 转换为 Decimal 对象的脚本重写器示例:
def 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')"
>>> exec(s)
-3.21716034272e-007
>>> exec(decistmt(s))
-3.217160342717258261933904529E-7
"""
result = []
g = generate_tokens(StringIO(s).readline) # tokenize the string
for toknum, tokval, _, _, _ in g:
if toknum == NUMBER and '.' in tokval: # replace NUMBER tokens
result.extend([
(NAME, 'Decimal'),
(OP, '('),
(STRING, repr(tokval)),
(OP, ')')
])
else:
result.append((toknum, tokval))
return untokenize(result)