tokenize — Tokenizer for Python source¶
Вихідний код: Lib/tokenize.py
The tokenize module provides a lexical scanner for Python source code,
implemented in Python. The scanner in this module returns comments as tokens
as well, making it useful for implementing «pretty-printers», including
colorizers for on-screen displays.
To simplify token stream handling, all operator and
delimiter tokens and Ellipsis are returned using
the generic OP token type.
The TokenInfo.exact_type property gives the exact token type.
Попередження
Note that the functions in this module are only designed to parse
syntactically valid Python code (code that does not raise when parsed
using ast.parse()). The behavior of the functions in this module is
undefined when providing invalid Python code and it can change at any
point.
Tokenizing input¶
Основною точкою входу є generator:
- tokenize.tokenize(readline)¶
Для генератора
tokenize()потрібен один аргумент, readline, який має бути викликаним об’єктом, який забезпечує той самий інтерфейс, що й методio.IOBase.readline()файлових об’єктів. Кожен виклик функції має повертати один рядок введення у вигляді байтів.The generator produces
TokenInfoobjects.Змінено в версії 3.1: Changed to yield
TokenInfoobjects instead of plain tuples.tokenize()визначає вихідне кодування файлу, шукаючи специфікацію UTF-8 або кодування cookie, відповідно до PEP 263.
- tokenize.generate_tokens(readline)¶
Токенізуйте джерело, яке читає рядки Unicode замість байтів.
Як і
tokenize(), аргумент readline є викликом, що повертає один рядок введення. Однакgenerate_tokens()очікує, що readline повертатиме об’єкт str, а не байти.The result is an iterator yielding
TokenInfoobjects, exactly liketokenize(). It does not yield anENCODINGtoken.
- class tokenize.TokenInfo(type, string, start, end, line)¶
A named tuple describing a token. It has five fields and an additional
exact_typeproperty.Added in version 3.1.
- type¶
An integer identifying the token type, as defined by the constants in
token, such asNAMEandSTRING. Operators and delimiters have typeOP; useexact_typefor their specific token type.
- string¶
The token text as a
str. ForSTRINGtokens, this includes the quotes, any prefix, and escape sequences, without evaluating them.For an
ENCODINGtoken, this is the encoding name. Tokens inserted without corresponding source text can have an empty string. InFSTRING_MIDDLEandTSTRING_MIDDLEtokens, doubled braces are replaced by single braces.
- start¶
A 2-tuple
(srow, scol)of ints specifying the inclusive start position of the token in the source. Rows are numbered from 1 and columns from 0. Columns count Unicode code points; a tab counts as one column, without expanding it to a tab stop.For an
ENCODINGtoken, this is(0, 0).
- end¶
A 2-tuple
(erow, ecol)of ints specifying the exclusive end position of the token. Rows are numbered from 1 and columns from 0. For a token spanning multiple lines, erow is the final row and ecol is the column on that row.For example, the name
spamat the beginning of the first line hasstartequal to(1, 0)andendequal to(1, 4).For an
ENCODINGtoken, this is(0, 0). ANEWLINEorNLtoken inserted at the end of input without a final newline can have an end column one beyond the source text.
All constants from the token module are also exported from
tokenize.
Ще одна функція передбачена для зворотного процесу токенізації. Це корисно для створення інструментів, які токенізують сценарій, змінюють потік маркерів і записують назад змінений сценарій.
- tokenize.untokenize(iterable)¶
Перетворює маркери назад у вихідний код Python. iterable має повертати послідовності принаймні з двома елементами, типом маркера та рядком маркера. Будь-які додаткові елементи послідовності ігноруються.
The result is guaranteed to tokenize back to match the input so that the conversion is lossless and round-trips are assured. The guarantee applies only to the token type and token string as the spacing between tokens (column positions) may change.
Він повертає байти, закодовані за допомогою маркера
ENCODING, який є першою послідовністю маркерів, виведеноюtokenize(). Якщо у вхідних даних немає маркера кодування, натомість повертається str.
tokenize() має визначити кодування вихідних файлів, які він токенізує. Доступна функція, яку він використовує для цього:
- tokenize.detect_encoding(readline)¶
Функція
detect_encoding()використовується для визначення кодування, яке слід використовувати для декодування вихідного файлу Python. Для нього потрібен один аргумент, readline, так само, як і генераторtokenize().Він викличе readline щонайбільше двічі та поверне використане кодування (як рядок) і список будь-яких рядків (не декодованих із байтів), які він прочитав.
Він визначає кодування за наявністю специфікації UTF-8 або файлу cookie кодування, як зазначено в PEP 263. Якщо і специфікація, і файл cookie присутні, але не узгоджуються, виникне
SyntaxError. Зауважте, що якщо специфікацію буде знайдено, як кодування буде повернуто'utf-8-sig.Якщо кодування не вказано, буде повернено значення за замовчуванням
'utf-8.Використовуйте
open()для відкриття вихідних файлів Python: він використовуєdetect_encoding()для визначення кодування файлу.
- tokenize.open(filename)¶
Відкрийте файл у режимі лише для читання, використовуючи кодування, визначене
detect_encoding().Added in version 3.2.
- exception tokenize.TokenError¶
Викликається, коли рядок документа або вираз, які можуть бути розділені на кілька рядків, не завершені ніде у файлі, наприклад:
"""Beginning of docstring
або:
[1, 2, 3
Command-line usage¶
Added in version 3.3.
The tokenize module can be executed as a script from the command line.
It is as simple as:
python -m tokenize [-e] [filename.py]
Приймаються такі варіанти:
- -h, --help¶
показати це довідкове повідомлення та вийти
- -e, --exact¶
відображати імена токенів, використовуючи точний тип
Якщо вказано filename.py, його вміст токенізується до stdout. В іншому випадку токенізація виконується на stdin.
Added in version 3.15: Output is in color by default and can be controlled using environment variables.
Приклади¶
Приклад сценарію переписувача, який перетворює плаваючі літерали в десяткові об’єкти:
from tokenize import tokenize, untokenize, NUMBER, STRING, NAME, OP
from io import BytesIO
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'))"
The format of the exponent is inherited from the platform C library.
Known cases are "e-007" (Windows) and "e-07" (not Windows). Since
we're only showing 12 digits, and the 13th isn't close to 5, the
rest of the output should be platform-independent.
>>> exec(s) #doctest: +ELLIPSIS
-3.21716034272e-0...7
Output from calculations with Decimal should be identical across all
platforms.
>>> exec(decistmt(s))
-3.217160342717258261933904529E-7
"""
result = []
g = tokenize(BytesIO(s.encode('utf-8')).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).decode('utf-8')
Приклад токенізації з командного рядка. Сценарій:
def say_hello():
print("Hello, World!")
say_hello()
will be tokenized to the following output where the first column is the range of the line/column coordinates where the token is found, the second column is the name of the token, and the final column is the value of the token (if any):
$ python -m tokenize hello.py
0,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:
$ python -m tokenize -e hello.py
0,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 ''
Приклад токенізації файлу програмним шляхом, зчитування рядків Unicode замість байтів за допомогою generate_tokens():
import tokenize
with tokenize.open('hello.py') as f:
tokens = tokenize.generate_tokens(f.readline)
for token in tokens:
print(token)
Або читання байтів безпосередньо за допомогою tokenize():
import tokenize
with open('hello.py', 'rb') as f:
tokens = tokenize.tokenize(f.readline)
for token in tokens:
print(token)