tokenize — 파이썬 소스를 위한 토크나이저¶
소스 코드: Lib/tokenize.py
tokenize 모듈은 Python 소스 코드를 위한 어휘 스캐너를 제공하며, Python으로 구현되었습니다. 이 모듈의 스캐너는 주석도 토큰으로 반환하므로, 화면 디스플레이용 색상 표시기를 포함한 “pretty-printers”를 구현하는 데 유용합니다.
토큰 스트림 처리를 단순화하기 위해, 모든 연산자와 구분자 토큰과 Ellipsis는 범용 OP 토큰 유형을 사용하여 반환됩니다. 정확한 유형은 tokenize.tokenize()에서 반환된 네임드 튜플의 exact_type 프로퍼티를 확인하여 파악할 수 있습니다.
경고
이 모듈의 함수는 구문적으로 유효한 Python 코드(:func:`ast.parse`를 사용하여 파싱할 때 오류를 발생시키지 않는 코드)를 구문 분석하도록 설계되었음에 유의하십시오. 이 모듈의 동작은 유효하지 않은 Python 코드를 제공할 경우 정의되지 않으며, 언제든지 변경될 수 있습니다.
입력 토큰화하기¶
기본 진입점은 제너레이터입니다:
- tokenize.tokenize(readline)¶
tokenize()제너레이터는 하나의 인자 readline을 요구합니다. 이 인자는 파일 객체의io.IOBase.readline()메서드와 같은 인터페이스를 제공하는 콜러블 객체여야 합니다. 함수를 호출할 때마다 한 줄의 입력을 바이트열로 반환해야 합니다.제너레이터는 다음 멤버를 갖는 5-튜플을 생성합니다: 토큰 유형; 토큰 문자열; 토큰이 소스에서 시작하는 줄과 열을 지정하는 정수의 2-튜플
(srow, scol); 토큰이 소스에서 끝나는 줄과 열을 지정하는 정수의 2-튜플(erow, ecol)과 토큰이 발견된 줄. 전달된 줄(마지막 튜플 항목)은 물리적 줄입니다. 5-튜플은 필드 이름이type string start end line인 네임드 튜플로 반환됩니다.반환된 네임드 튜플에는
OP토큰에 대한 정확한 연산자 유형이 포함된exact_type이라는 추가 프로퍼티가 있습니다. 다른 모든 토큰 유형에서exact_type은 네임드 튜플type필드와 같습니다.버전 3.1에서 변경: 네임드 튜플에 대한 지원이 추가되었습니다.
버전 3.3에서 변경:
exact_type에 대한 지원이 추가되었습니다.tokenize()는 PEP 263에 따라 UTF-8 BOM이나 인코딩 쿠키를 찾아 파일의 소스 인코딩을 결정합니다.
- tokenize.generate_tokens(readline)¶
바이트열 대신에 유니코드 문자열을 읽는 소스를 토큰화합니다.
tokenize()와 마찬가지로, readline 인자는 한 줄의 입력을 반환하는 콜러블입니다. 그러나,generate_tokens()는 readline이 바이트열이 아닌 문자열 객체를 반환할 것으로 기대합니다.결과는 정확히
tokenize()처럼 네임드 튜플을 산출하는 이터레이터입니다.ENCODING토큰을 산출하지 않습니다.
token 모듈의 모든 상수는 :mod:`!tokenize`에서 또한 export됩니다.
토큰화 프로세스를 역전시키는 또 다른 함수가 제공됩니다. 이것은 스크립트를 토큰화하고, 토큰 스트림을 수정한 후, 수정된 스크립트를 다시 쓰는 도구를 만드는 데 유용합니다.
- 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
명령줄 사용법¶
Added in version 3.3.
tokenize 모듈은 명령줄에서 스크립트로 실행될 수 있습니다. 다음과 같이 간단합니다:
python -m tokenize [-e] [filename.py]
허용되는 옵션은 다음과 같습니다:
- -h, --help¶
이 도움말 메시지를 표시하고 종료합니다
- -e, --exact¶
정확한 유형(exact_type)을 사용하여 토큰 이름을 표시합니다
filename.py가 지정되면 그 내용은 표준출력(stdout)으로 토큰화됩니다. 그렇지 않으면, 표준입력(stdin)에 대해 토큰화가 수행됩니다.
Added in version 3.15: 출력은 기본적으로 색상이 적용되며, :ref:`environment variables <using-on-controlling-color>`를 사용하여 제어할 수 있습니다.
예제¶
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()
는 다음 출력으로 토큰화됩니다. 여기서 첫 번째 열은 토큰이 발견된 줄/열 좌표의 범위이고, 두 번째 열은 토큰의 이름이며, 마지막 열은 토큰의 값입니다 (있다면):
$ 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)