1

recursive_reprPython 3.2 中引入的模块中的函数reprlib具有以下 源代码

def recursive_repr(fillvalue='...'):
    'Decorator to make a repr function return fillvalue for a recursive call'

    def decorating_function(user_function):
        repr_running = set()

        def wrapper(self):
            key = id(self), get_ident()
            if key in repr_running:
                return fillvalue
            repr_running.add(key)
            try:
                result = user_function(self)
            finally:
                repr_running.discard(key)
            return result

        # Can't use functools.wraps() here because of bootstrap issues
        wrapper.__module__ = getattr(user_function, '__module__')
        wrapper.__doc__ = getattr(user_function, '__doc__')
        wrapper.__name__ = getattr(user_function, '__name__')
        wrapper.__annotations__ = getattr(user_function, '__annotations__', {})
        return wrapper

    return decorating_function

key识别特定功能__repr__设置为。(id(self), get_ident())

为什么self它本身不被用作钥匙?为什么get_ident需要?

4

1 回答 1

1

考虑这段代码:

a = []
b = []
a.append(b)
b.append(a)
a == b

这会导致堆栈溢出。但是算法需要安全地处理这种情况。如果您放入self集合中,它将比较使用==并且算法将失败。所以我们id(self)改用它不尝试检查对象的相等性。我们只关心它是否是完全相同的对象。

至于get_indent,考虑如果两个线程同时尝试使用代码,这个算法会发生什么。该repr_running集合在所有线程之间共享。但是,如果多个线程开始从该集合中添加和删除元素,则不知道会发生什么。get_ident()对运行它的线程来说是唯一的,所以通过将它与密钥一起使用,我们知道所有线程都将使用不同的密钥并且没问题。

于 2012-07-31T20:04:04.947 回答