tokenize — 파이썬 소스를 위한 토크나이저¶
소스 코드: 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¶
기본 진입점은 제너레이터입니다:
- tokenize.tokenize(readline)¶
tokenize()제너레이터는 하나의 인자 readline을 요구합니다. 이 인자는 파일 객체의io.IOBase.readline()메서드와 같은 인터페이스를 제공하는 콜러블 객체여야 합니다. 함수를 호출할 때마다 한 줄의 입력을 바이트열로 반환해야 합니다.The generator produces
TokenInfoobjects.버전 3.1에서 변경: Changed to yield
TokenInfoobjects instead of plain tuples.tokenize()는 PEP 263에 따라 UTF-8 BOM이나 인코딩 쿠키를 찾아 파일의 소스 인코딩을 결정합니다.
- tokenize.generate_tokens(readline)¶
바이트열 대신에 유니코드 문자열을 읽는 소스를 토큰화합니다.
tokenize()와 마찬가지로, readline 인자는 한 줄의 입력을 반환하는 콜러블입니다. 그러나,generate_tokens()는 readline이 바이트열이 아닌 문자열 객체를 반환할 것으로 기대합니다.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)¶
토큰을 파이썬 소스 코드로 역 변환합니다. iterable은 최소한 토큰 유형과 토큰 문자열의 두 요소가 있는 시퀀스를 반환해야 합니다. 추가 시퀀스 요소는 무시됩니다.
결과는 다시 토큰화하면 입력과 일치함이 보장되어, 변환은 무손실이고 왕복이 보장됩니다. 보증은 토큰 유형과 토큰 문자열에만 적용되어, 토큰 간의 간격(열 위치)은 변경될 수 있습니다.
tokenize()에 의해 출력되는 첫 번째 토큰 시퀀스인ENCODING토큰을 사용하여 인코딩된 바이트열을 반환합니다. 입력에 인코딩 토큰이 없으면, 대신 str을 반환합니다.
tokenize()는 토큰화하는 소스 파일의 인코딩을 감지해야 합니다. 이 작업을 수행하는 데 사용되는 함수를 사용할 수 있습니다:
- tokenize.detect_encoding(readline)¶
detect_encoding()함수는 파이썬 소스 파일을 디코딩할 때 사용해야 하는 인코딩을 감지하는 데 사용됩니다.tokenize()제너레이터와 같은 방식으로, 하나의 인자 readline을 요구합니다.readline을 최대 두 번 호출하고, 사용된 인코딩(문자열로)과 읽은 줄들(바이트열에서 디코드 되지 않습니다)의 리스트를 반환합니다.
PEP 263에 지정된 대로 UTF-8 BOM이나 인코딩 쿠키의 존재로부터 인코딩을 검색합니다. BOM과 쿠키가 모두 있지만 서로 일치하지 않으면
SyntaxError가 발생합니다. BOM이 발견되면,'utf-8-sig'가 인코딩으로 반환됩니다.인코딩이 지정되지 않으면, 기본값인
'utf-8'이 반환됩니다.open()을 사용하여 파이썬 소스 파일을 여십시오: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¶
정확한 유형(exact_type)을 사용하여 토큰 이름을 표시합니다
filename.py가 지정되면 그 내용은 표준출력(stdout)으로 토큰화됩니다. 그렇지 않으면, 표준입력(stdin)에 대해 토큰화가 수행됩니다.
Added in version 3.15: Output is in color by default and can be controlled using environment variables.
예제¶
float 리터럴을 Decimal 객체로 변환하는 스크립트 재 작성기의 예제:
from tokenize import tokenize, untokenize, NUMBER, STRING, NAME, OP
from io import BytesIO
def decistmt(s):
"""문장 문자열에 있는 float를 Decimal로 치환합니다.
>>> from decimal import Decimal
>>> s = 'print(+21.3e-5*-.1234/81.7)'
>>> decistmt(s)
"print (+Decimal ('21.3e-5')*-Decimal ('.1234')/Decimal ('81.7'))"
지수 형식은 플랫폼 C 라이브러리에서 상속됩니다. 알려진 경우는 "e-007" (윈도우) 와 "e-07"
(윈도우 외) 입니다. 우리는 단지 12자리 숫자를 보여주고 있고, 13번째 숫자는 5에 가깝지
않으므로, 출력의 나머지 부분은 플랫폼 독립적이어야 합니다.
>>> exec(s) #doctest: +ELLIPSIS
-3.21716034272e-0...7
Decimal을 사용한 계산의 결과는 모든 플랫폼에서 같아야 합니다.
>>> exec(decistmt(s))
-3.217160342717258261933904529E-7
"""
result = []
g = tokenize(BytesIO(s.encode('utf-8')).readline) # 문자열을 토큰화합니다
for toknum, tokval, _, _, _ in g:
if toknum == NUMBER and '.' in tokval: # NUMBER 토큰을 바꿔치기합니다
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 옵션을 사용하여 표시할 수 있습니다:
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 ''
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)