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

  The keyword arguments of the constructor can be used as a shortcut to set the attributes of the `Repr` instance. Which means that the following initialization:

      aRepr = reprlib.Repr(maxlevel=3)

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

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

  See section Repr Objects for more information about `Repr` attributes.

  バージョン 3.12 で変更: Allow attributes to be set via keyword arguments.

reprlib.aRepr

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

reprlib.repr(obj)

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

In addition to size-limiting tools, the module also provides a decorator for detecting recursive calls to `__repr__()` and substituting a placeholder string instead.

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

  Decorator for `__repr__()` methods to detect recursive calls within the same thread. If a recursive call is made, the fillvalue is returned, otherwise, the usual `__repr__()` call is made. For example:

      >>> 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

  This string is displayed for recursive references. It defaults to `...`.

  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

  If this attribute is set to `None` (the default), the output is formatted with no line breaks or indentation, like the standard `repr()`. For example:

      >>> 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']

  If `indent` is set to a string, each recursion level is placed on its own line, indented by that string:

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

  Setting `indent` to a positive integer value behaves as if it was set to a string with that number of spaces:

      >>> 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オブジェクトをサブクラス化する

The use of dynamic dispatching by `Repr.repr1()` allows subclasses of `Repr` to add support for additional built-in object types or to modify the handling of types already supported. This example shows how special support for file objects could be added:

    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))         # prints '<stdin>'

    <stdin>