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

源代碼: Lib/reprlib.py


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

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

class reprlib.Repr?

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

reprlib.aRepr?

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

reprlib.repr(obj)?

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

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

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

用于為 __repr__() 方法檢測同一線(xiàn)程內部遞歸調用的裝飾器。 如果執行了遞歸調用,則會(huì )返回 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'>

3.2 新版功能.

Repr 對象?

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

Repr.fillvalue?

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

3.11 新版功能.

Repr.maxlevel?

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

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

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

Repr.maxlong?

表示整數的最大字符數量。 數碼會(huì )從中間被丟棄。 默認值為 40。

Repr.maxstring?

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

Repr.maxother?

此限制用于控制在 Repr 對象上沒(méi)有特定的格式化方法可用的對象類(lèi)型的大小。 它會(huì )以類(lèi)似 maxstring 的方式被應用。 默認值為 20。

Repr.repr(obj)?

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

Repr.repr1(obj, level)?

repr() 使用的遞歸實(shí)現。 此方法使用 obj 的類(lèi)型來(lái)確定要調用哪個(gè)格式化方法,并傳入 objlevel。 類(lèi)型專(zhuān)屬的方法應當調用 repr1() 來(lái)執行遞歸格式化,在遞歸調用中使用 level - 1 作為 level 的值。

Repr.repr_TYPE(obj, level)

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

子類(lèi)化 Repr 對象?

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

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