Python データ型における Repr.fillvalue の詳細解説


このモジュールには、Repr クラス、reprlib.aRepr インスタンス、そして reprlib.repr() 関数が含まれています。

Repr クラス

Repr クラスは、オブジェクト表現のフォーマットに使用されるサービスを提供します。このクラスには、以下の属性とメソッドが用意されています。

属性

  • indent: 各レベルのインデント文字列 (デフォルト: None)
  • fillvalue: 再帰呼び出しが検出された場合に使用するプレースホルダー文字列 (デフォルト: '...')
  • maxlong: 長整数の最大桁数 (デフォルト: 40)
  • maxstring: 文字列の最大長さ (デフォルト: 30)
  • maxarray: NumPy 配列の最大要素数 (デフォルト: 5)
  • maxdeque: デキューの最大要素数 (デフォルト: 6)
  • maxfrozenset: 凍結集合の最大要素数 (デフォルト: 6)
  • maxset: 集合の最大要素数 (デフォルト: 6)
  • maxtuple: タプルの最大要素数 (デフォルト: 6)
  • maxlist: リストの最大要素数 (デフォルト: 6)
  • maxdict: 辞書の最大要素数 (デフォルト: 4)
  • maxlevel: 再帰的表現の最大深さ (デフォルト: 6)

メソッド

  • repr1(obj, level): オブジェクト obj の表現を再帰的に返します。
  • repr(obj): オブジェクト obj の表現を返します。

reprlib.aRepr インスタンス

reprlib.aReprRepr クラスのインスタンスであり、reprlib.repr() 関数で使用されます。このインスタンスの属性を変更することで、repr() 関数とデバッガで使用されるサイズ制限を変更することができます。

reprlib.repr() 関数

reprlib.repr() 関数は、repr() 関数と同様の機能を提供しますが、以下の点が異なります。

  • 再帰呼び出しを検出して、fillvalue 属性で指定されたプレースホルダー文字列に置き換えることができます。
  • 結果の文字列の長さに制限を設けることができます。

reprlib.Repr.fillvalue 属性は、再帰呼び出しが検出された場合に reprlib.repr() 関数によって返されるプレースホルダー文字列を指定するために使用されます。これは、ネストされたデータ構造を表現する場合に、結果の文字列が肥大化することを防ぐのに役立ちます。

from reprlib import Repr

r = Repr(fillvalue='[RECURSIVE]')

data = [1, 2, [3, 4, data]]
print(repr(data))  # 出力: [1, 2, [3, 4, [RECURSIVE]]]
print(r.repr(data))  # 出力: [1, 2, [3, 4, [RECURSIVE]]]


from reprlib import Repr

def my_repr(obj):
    r = Repr(fillvalue='**RECURSIVE**')
    return r.repr(obj)

data = [1, 2, [3, 4, data]]
print(my_repr(data))

このコードは以下の出力を生成します。

[1, 2, [3, 4, **RECURSIVE**]]

上記の例では、my_repr 関数は Repr クラスのインスタンスを作成し、fillvalue 属性を **RECURSIVE** に設定します。次に、このインスタンスを使用して data リストの表現を生成します。

別の例として、reprlib.Repr クラスのインスタンスを作成し、他の属性を変更する方法を示します。

from reprlib import Repr

def my_repr(obj):
    r = Repr(maxlevel=2, maxdict=2, maxlist=2, maxstring=10)
    return r.repr(obj)

data = [1, 2, {3: 4, 5: 6}, 'This is a long string']
print(my_repr(data))
[1, 2, {3: 4, 5: 6}, 'This is a...']

上記の例では、my_repr 関数は Repr クラスのインスタンスを作成し、以下の属性を設定します。

  • maxstring: 文字列の最大長さ (10)
  • maxlist: リストの最大要素数 (2)
  • maxdict: 辞書の最大要素数 (2)
  • maxlevel: 再帰的表現の最大深さ (2)


  • 再帰呼び出しが検出されたかどうかを判断するロジックは単純です。
  • プレースホルダー文字列は 1 つの文字列にしか設定できません。

これらの制限を克服するために、reprlib.Repr.fillvalue の代替方法をいくつか検討することができます。

カスタム __repr__() メソッドを使用する

最も柔軟な方法は、カスタム __repr__() メソッドを実装することです。このメソッドでは、再帰呼び出しを検出して、独自のロジックに基づいてカスタム表現を生成することができます。

class MyData:
    def __init__(self, data):
        self.data = data

    def __repr__(self):
        if hasattr(self, '_repr_visited'):
            return '...'
        else:
            self._repr_visited = True
            try:
                return f'<MyData: {repr(self.data)}>'
            finally:
                del self._repr_visited

data = MyData([1, 2, [3, 4, data]])
print(repr(data))  # 出力: <MyData: [1, 2, [3, 4, ...]]>

上記の例では、MyData クラスはカスタム __repr__() メソッドを実装しています。このメソッドは、hasattr() 関数を使用してオブジェクトが以前に表現されたかどうかを確認します。オブジェクトが以前に表現された場合は、... を返します。そうでなければ、_repr_visited 属性を設定し、repr() 関数を使用して self.data の表現を生成します。最後に、del 演算子を使用して _repr_visited 属性を削除します。

reprlib モジュールには、@recursive_repr デコレータが用意されています。このデコレータは、カスタム __repr__() メソッドを実装する際に役立ちます。

from reprlib import recursive_repr

@recursive_repr()
class MyData:
    def __init__(self, data):
        self.data = data

    def __repr__(self):
        return f'<MyData: {repr(self.data)}>'

data = MyData([1, 2, [3, 4, data]])
print(repr(data))  # 出力: <MyData: [1, 2, [3, 4, ...]]>

上記の例は、MyData クラスに @recursive_repr デコレータを適用しています。このデコレータは、__repr__() メソッドが再帰呼び出しを行っているかどうかを自動的に検出します。再帰呼び出しが検出された場合は、fillvalue 属性で指定されたプレースホルダー文字列が返されます。

import prettyprint

data = [1, 2, [3, 4, data]]
print(prettyprint.pp(data))

上記の例は、prettyprint ライブラリを使用して data リストの表現を生成します。出力は次のようになります。

[
    1,
    2,
    [
        3,
        4,
        [
            # 省略
        ]
    ]
]