reprlib --- もう一つの repr() の実装

ソースコード: Lib/reprlib.py


reprlib モジュールは、結果の文字列のサイズに対する制限付きでオブジェクト表現を生成するための手段を提供します。これは Python デバッガの中で使用されており、他の文脈でも同様に役に立つかもしれません。

このモジュールはクラスとインスタンス、それに関数を提供します:

class reprlib.Repr(*, maxlevel=6, maxtuple=6, maxlist=6, maxarray=5, maxdict=4, maxset=6, maxfrozenset=6, maxdeque=6, maxstring=30, maxlong=40, maxother=30, fillvalue='...', indent=None)

組み込み関数 repr() に似た関数を実装するために役に立つフォーマット用サービスを提供します。 過度に長い表現を作り出さないようにするための大きさの制限をオブジェクト型ごとに設定できます。

コンストラクタのキーワード引数を使うと、Repr インスタンスの属性を簡単に設定できます。 例えば、次のように初期化できます。

aRepr = reprlib.Repr(maxlevel=3)

は、次のコードと等しいです:

aRepr = reprlib.Repr()
aRepr.maxlevel = 3

Repr の属性について詳しくは Repr Objects の節を参照してください。

バージョン 3.12 で変更: キーワード引数で属性を設定できるようになりました。

reprlib.aRepr

これは下で説明される repr() 関数を提供するために使われる Repr のインスタンスです。このオブジェクトの属性を変更すると、 repr() と Python デバッガが使うサイズ制限に影響します。

reprlib.repr(obj)

これは aRepr の repr() メソッドです。同じ名前の組み込み関数が返す文字列と似ていますが、最大サイズに制限のある文字列を返します。

サイズを制限するツールに加えて、このモジュールは __repr__() の再帰呼び出しを検出し、代わりにプレースホルダーの文字列を返すデコレータも提供します。

@reprlib.recursive_repr(fillvalue='...')

同じスレッド内での再帰呼び出しを検出する、__repr__() メソッド用のデコレータです。 再帰呼び出しが行われた場合は fillvalue を返し、それ以外の場合は通常の __repr__() 呼び出しを行います。 例えば、次のように使います:

>>> from reprlib import recursive_repr
>>> class MyList(list):
...     @recursive_repr()
...     def __repr__(self):
...         return '<' + '|'.join(map(repr, self)) + '>'
...
>>> m = MyList('abc')
>>> m.append(m)
>>> m.append('x')
>>> print(m)
<'a'|'b'|'c'|...|'x'>

Added in version 3.2.

Reprオブジェクト

Repr インスタンスはオブジェクト型毎に表現する文字列のサイズを制限するために使えるいくつかの属性と、特定のオブジェクト型をフォーマットするメソッドを提供します。

Repr.fillvalue

再帰的な参照に対して表示する文字列です。 デフォルトは ... です。

Added in version 3.11.

Repr.maxlevel

再帰的な表現を作る場合の深さ制限。デフォルトは 6 です。

Repr.maxdict
Repr.maxlist
Repr.maxtuple
Repr.maxset
Repr.maxfrozenset
Repr.maxdeque
Repr.maxarray

指定されたオブジェクト型に対するエントリ表現の数についての制限。 maxdict に対するデフォルトは 4 で、 maxarray は 5 、その他に対しては 6 です。

Repr.maxlong

整数の表現のおける文字数の最大値。中央の数字が抜け落ちます。デフォルトは 40 です。

Repr.maxstring

文字列の表現における文字数の制限。文字列の"通常の"表現は文字の「元」として使われることに注意してください。表現にエスケープシーケンスが必要とされる場合、表現が短縮されるときにこれらのエスケープシーケンスの形式は崩れます。デフォルトは 30 です。

Repr.maxother

この制限は Repr オブジェクトに利用できる特定のフォーマットメソッドがないオブジェクト型のサイズをコントロールするために使われます。 maxstring と同じようなやり方で適用されます。デフォルトは 20 です。

Repr.indent

この属性が None (デフォルト) の場合、標準の repr() と同様に、改行やインデントなしで出力を書式化します。 例えば、次のようになります:

>>> example = [
...     1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham']
>>> import reprlib
>>> aRepr = reprlib.Repr()
>>> print(aRepr.repr(example))
[1, 'spam', {'a': 2, 'b': 'spam eggs', 'c': {3: 4.5, 6: []}}, 'ham']

indent に文字列を設定すると、再帰の各レベルを別の行に配置し、その文字列でインデントします:

>>> aRepr.indent = '-->'
>>> print(aRepr.repr(example))
[
-->1,
-->'spam',
-->{
-->-->'a': 2,
-->-->'b': 'spam eggs',
-->-->'c': {
-->-->-->3: 4.5,
-->-->-->6: [],
-->-->},
-->},
-->'ham',
]

indent に正の整数を設定すると、その個数の空白からなる文字列を設定した場合と同じように動作します:

>>> aRepr.indent = 4
>>> print(aRepr.repr(example))
[
    1,
    'spam',
    {
        'a': 2,
        'b': 'spam eggs',
        'c': {
            3: 4.5,
            6: [],
        },
    },
    'ham',
]

Added in version 3.12.

Repr.repr(obj)

このインスタンスで設定されたフォーマットを使う、組み込み repr() と等価なもの。

Repr.repr1(obj, level)

repr() が使う再帰的な実装。 obj の型を使ってどのフォーマットメソッドを呼び出すかを決定し、それに obj と level を渡します。 再帰呼び出しにおいて level の値に対して level - 1 を与える再帰的なフォーマットを実行するために、型に固有のメソッドは repr1() を呼び出します。

Repr.repr_TYPE(obj, level)

型名に基づく名前をもつメソッドとして、特定の型に対するフォーマットメソッドは実装されます。メソッド名では、 TYPE は '_'.join(type(obj).__name__.split()) に置き換えられます。これらのメソッドへのディスパッチは repr1() によって処理されます。再帰的に値をフォーマットする必要がある型固有のメソッドは、 self.repr1(subobj, level - 1) を呼び出します。

Reprオブジェクトをサブクラス化する

Repr.repr1() は動的なディスパッチを使うため、Repr のサブクラスで別の組み込みオブジェクト型への対応を追加したり、サポート済みの型の扱いを変更したりできます。 次の例は、ファイルオブジェクト向けの特別な処理を追加する方法を示します:

import reprlib
import sys

class MyRepr(reprlib.Repr):

    def repr_TextIOWrapper(self, obj, level):
        if obj.name in {'<stdin>', '<stdout>', '<stderr>'}:
            return obj.name
        return repr(obj)

aRepr = MyRepr()
print(aRepr.repr(sys.stdin))         # '<stdin>' と表示する
<stdin>