tokenize
tokenize - 用于Python源代码的Tokenizer
源代码:
Lib / tokenize.py
该tokenize
模块为Python源代码提供了一个词法扫描器,并以Python实现。该模块中的扫描器也将评论作为标记返回,从而使其对于实现“漂亮打印机”(包括用于屏幕显示的着色器)非常有用。
为了简化标记流处理,使用通用标记类型返回所有运算符和分隔符令牌token.OP
。通过检查tokenize.generate_tokens()
标识特定运算符标记的字符序列返回的元组的第二个字段(包含匹配的实际标记字符串)可以确定确切的类型。
主要入口点是一个生成器:
tokenize.generate_tokens(readline)
generate_tokens()生成器需要一个参数readline,它必须是一个可调用的对象,它提供与内置文件对象的readline()方法相同的接口(请参阅文件对象部分)。 对函数的每次调用都应以字符串的形式返回一行输入。 另外,readline可能是一个可调用的对象,通过提高StopIteration来表示完成。
生成器生成这些成员的5元组:令牌类型; 令牌字符串; 一个2元组(srow, scol)
ints,用于指定源中源标记开始的行和列; 一个2元组(erow, ecol)
inint,用于指定令牌在源中结束的行和列; 和找到令牌的行。传递的行(最后一个元组项)是逻辑
行; 包括延续线。
2.2版本中的新功能。
为保持向后兼容性而保留较旧的入口点:
tokenize.tokenize(readline[, tokeneater])
该tokenize()
函数接受两个参数:一个表示输入流,一个提供输出机制tokenize()
。
第一个参数readline
必须是一个可调用对象,它提供与readline()
内置文件对象方法相同的接口(请参见文件对象部分)。对函数的每次调用都应以字符串的形式返回一行输入。或者,readline
可能是一个可调用的对象,通过提升表示完成StopIteration
。
在版本2.5中进行了更改:添加了StopIteration
支持。
第二个参数tokeneater
也必须是可调用的对象。它为每个标记调用一次,有五个参数,对应于生成的元组generate_tokens()
。
token
模块中的所有常量也会从中导出tokenize
,以及可能通过以下方式传递给tokeneater
函数的两个附加标记类型值tokenize()
:
tokenize.COMMENT
令牌值用于表示注释。
tokenize.NL
令牌值用于指示非终止换行符。NEWLINE标记表示Python代码的逻辑行结束; 当一条逻辑代码行在多条物理线路上继续时,会生成NL令牌。
提供另一个功能来反转标记化过程。这对于创建令牌化脚本,修改令牌流和回写修改的脚本的工具很有用。
tokenize.untokenize(iterable)
将令牌转换回Python源代码。该迭代
必须具有至少两个元件,所述令牌类型和令牌字符串返回序列。任何其他序列元素都将被忽略。
重建的脚本作为单个字符串返回。结果保证将标记返回以匹配输入,以便转换无损并确保往返。保证仅适用于令牌类型和令牌字符串,因为令牌之间的间距(列位置)可能会发生变化。
2.5版本中的新功能。
exception tokenize.TokenError
当可能分成多行的文档字符串或表达式未在文件中的任何位置完成时引发,例如:
"""Beginning of
docstring
或者:
[1,
2,
3
请注意,未封闭的单引号字符串不会导致引发错误。它们被标记为ERRORTOKEN
,然后标记它们的内容。
将浮点文字转换为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)