簡體   English   中英

我如何處理Python中的遞歸repr()?

[英]How do I handle recursive repr()'s in Python?

我在Python中編寫了一個容器類型,我正在嘗試編寫一個健壯的__repr__方法,該方法正確處理容器包含自身的情況。

例如,以下是內置list作用:

>>> x = []
>>> x.append(x)
>>> repr(x)
'[[...]]'

用C語言編寫的CPython容器類型可以通過使用Py_ReprEnterPy_ReprLeave來實現此功能。 在純Python中是否有相同的功能,還是我需要創建自己的?

你可以創建自己的,但如果你想要正確地做它會有點痛苦:你不應該在對象本身上存儲一個'被repr'd'標記標志,因為那不是線程安全的。 相反,您可以存儲正在重新創建的線程本地實例集。

更便宜的解決方案是依賴於負責遞歸的內置repr ,例如:

def __init__(self, *list):
    self._list= list
def __repr__(self):
    return 'mything('+repr(self._list)[1:-1]+')')

只要遞歸循環中的一個對象導致Py_ReprEnter發生, repr就不能形成完整的循環。

如何創建線程本地實例集?

使用線程模塊:

class MyThing(object):
    _local= threading.local()
    _local.reprs= set()

    def __repr__(self):
        reprs= MyThing._local.reprs
        sid= id(self)
        if sid in reprs:
            return 'MyThing(...)'
        try:
            reprs.add(sid)
            return 'MyThing(%r)' % self.something
        finally:
            reprs.remove(sid)

如果您使用的是Python 3,則可以使用reprlib.recursive_repr裝飾器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM