前のトピックへ

31.6. keyword — Python キーワードチェック

次のトピックへ

31.8. tabnanny — あいまいなインデントの検出

このページ

31.7. tokenize — Pythonソースのためのトークナイザ

tokenize モジュールでは、Python で実装された Python ソースコードの字句解析器を提供します。さらに、このモジュールの字句解析器はコメントもトークンとして返します。このため、このモジュールはスクリーン上で表示する際の色付け機能 (colorizers) を含む “清書出力器 (pretty-printer)” を実装する上で便利です。

第一のエントリポイントはジェネレータ(generator)です:

tokenize.generate_tokens(readline)

generate_tokens() ジェネレータは一つの引数 readline を必要とします。この引数は呼び出し可能オブジェクトで、組み込みファイルオブジェクトにおける readline() メソッドと同じインタフェースを提供していなければなりません ( ファイルオブジェクト 節を参照してください)。この関数は呼び出しのたびに入力内の一行を文字列で返さなければなりません。

ジェネレータは 5 要素のタプルを返し、タプルは以下のメンバ: トークン型; トークン文字列; ソースコード中でトークンが始まる行と列を示す整数の2要素のタプル (srow, scol) ; ソースコード中でトークンが終わる行と列を示す整数の2要素のタプル (srow, scol) ; そして、トークンが見つかった行、からなります。渡される行は 論理 行です; 連続する行は一行に含められます。

バージョン 2.2 で追加.

後方互換性のために古いエントリポイントが残されています:

tokenize.tokenize(readline[, tokeneater])

tokenize() 関数は二つのパラメータを取ります: 一つは入力ストリームを表し、もう一つは tokenize() のための出力メカニズムを与えます。

最初のパラメータ、 readline は、組み込みファイルオブジェクトの readline() メソッドと同じインタフェイスを提供する呼び出し可能オブジェクトでなければなりません ( ファイルオブジェクト 節を参照)。この関数は呼び出しのたびに入力内の一行を文字列で返さなければなりません。もしくは、 readline を呼び出し可能オブジェクトで StopIteration を送出することで補完を知らせるものとすることもできます。

バージョン 2.5 で変更: StopIteration サポートの追加.

二番目のパラメータ tokeneater も呼び出し可能オブジェクトでなければなりません。この関数は各トークンに対して一度だけ呼び出され、 generate_tokens() が生成するタプルに対応する 5 つの引数をとります。

token モジュールの全ての定数は tokenize でも公開されており、これに加え、以下の二つのトークン値が tokenize()tokeneater 関数に渡される可能性があります:

tokenize.COMMENT

コメントであることを表すために使われるトークン値です。

tokenize.NL

終わりではない改行を表すために使われるトークン値。 NEWLINE トークンは Pythonコードの論理行の終わりを表します。 NLトークンはコードの論理行が複数の物理行にわたって続いているときに作られます。

もう一つの関数がトークン化プロセスを逆転するために提供されています。これは、スクリプトを字句解析し、トークンのストリームに変更を加え、変更されたスクリプトを書き戻すようなツールを作成する際に便利です。

tokenize.untokenize(iterable)

トークンの列を Python ソースコードに変換します。 iterable は少なくとも二つの要素、トークン型およびトークン文字列、からなるシーケンスを返します。その他のシーケンスの要素は無視されます。

再構築されたスクリプトは一つの文字列として返されます。得られる結果はもう一度字句解析すると入力と一致することが保証されるので、変換がロスレスでありラウンドトリップできることは間違いありません。この保証はトークン型およびトークン文字列に対してのものでトークン間のスペース (コラム位置)のようなものは変わることがあり得ます。

バージョン 2.5 で追加.

スクリプト書き換えの例で、浮動小数点数リテラルを 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)