reprlib --- 另一種 repr() 實(shí)現(xiàn)?

源代碼: Lib/reprlib.py


reprlib 模塊提供了一種對象表示的產(chǎn)生方式,它會對結(jié)果字符串的大小進(jìn)行限制。 該方式被用于 Python 調(diào)試器,也適用于某些其他場景。

此模塊提供了一個類、一個實(shí)例和一個函數(shù):

class reprlib.Repr?

該類提供了格式化服務(wù) 適用于實(shí)現(xiàn)與內(nèi)置 repr() 相似的方法;其中附加了針對不同對象類型的大小限制,以避免生成超長的表示。

reprlib.aRepr?

這是 Repr 的一個實(shí)例,用于提供如下所述的 repr() 函數(shù)。 改變此對象的屬性將會影響 repr() 和 Python 調(diào)試器所使用的大小限制。

reprlib.repr(obj)?

這是 aReprrepr() 方法。 它會返回與同名內(nèi)置函數(shù)所返回字符串相似的字符串,區(qū)別在于附帶了對多數(shù)類型的大小限制。

在大小限制工具以外,此模塊還提供了一個裝飾器,用于檢測對 __repr__() 的遞歸調(diào)用并改用一個占位符來替換。

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

用于為 __repr__() 方法檢測同一線程內(nèi)部遞歸調(diào)用的裝飾器。 如果執(zhí)行了遞歸調(diào)用,則會返回 fillvalue,否則執(zhí)行正常的 __repr__() 調(diào)用。 例如:

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

3.2 新版功能.

Repr 對象?

Repr 實(shí)例對象包含一些屬性可以用于為不同對象類型的表示提供大小限制,還包含一些方法可以格式化特定的對象類型。

Repr.fillvalue?

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

3.11 新版功能.

Repr.maxlevel?

創(chuàng)建遞歸表示形式的深度限制。 默認(rèn)為 6。

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

表示命名對象類型的條目數(shù)量限制。 對于 maxdict 的默認(rèn)值為 4,對于 maxarray5,對于其他則為 6。

Repr.maxlong?

表示整數(shù)的最大字符數(shù)量。 數(shù)碼會從中間被丟棄。 默認(rèn)值為 40。

Repr.maxstring?

表示字符串的字符數(shù)量限制。 請注意字符源會使用字符串的“正?!北硎拘问剑喝绻硎局行枰玫睫D(zhuǎn)義序列,在縮短表示時它們可能會被破壞。 默認(rèn)值為 30

Repr.maxother?

此限制用于控制在 Repr 對象上沒有特定的格式化方法可用的對象類型的大小。 它會以類似 maxstring 的方式被應(yīng)用。 默認(rèn)值為 20。

Repr.repr(obj)?

內(nèi)置 repr() 的等價形式,它使用實(shí)例專屬的格式化。

Repr.repr1(obj, level)?

repr() 使用的遞歸實(shí)現(xiàn)。 此方法使用 obj 的類型來確定要調(diào)用哪個格式化方法,并傳入 objlevel。 類型專屬的方法應(yīng)當(dāng)調(diào)用 repr1() 來執(zhí)行遞歸格式化,在遞歸調(diào)用中使用 level - 1 作為 level 的值。

Repr.repr_TYPE(obj, level)

特定類型的格式化方法會被實(shí)現(xiàn)為基于類型名稱來命名的方法。 在方法名稱中,TYPE 會被替換為 '_'.join(type(obj).__name__.split())。 對這些方法的分派會由 repr1() 來處理。 需要對值進(jìn)行遞歸格式化的類型專屬方法應(yīng)當(dāng)調(diào)用 self.repr1(subobj, level - 1)。

子類化 Repr 對象?

通過 Repr.repr1() 使用動態(tài)分派允許 Repr 的子類添加對額外內(nèi)置對象類型的支持,或是修改對已支持類型的處理。 這個例子演示了如何添加對文件對象的特殊支持:

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