werkzeug 0.6.1中Local的初始化是这样的:

class Local(object):
    __slots__ = ('__storage__', '__lock__')

    def __init__(self):
        object.__setattr__(self, '__storage__', {})
        object.__setattr__(self, '__lock__', allocate_lock())

我当时很奇怪为什么要用object.__setattr__, 而不是直接用self.__storage__, 当我直接用self.__storage__ = {}实现的时候才发现问题:

self.__storage__会调用__setattr__,而__setattr__中会调用self.__lock__.acquire(),因为此时self.__lock__还没有定义, 所以会调用self.__getattr__,而self.__getattr__中也会调用self.__lock__.acquire(), 此后就会一直调用self.__getattr__,最终导致StackOverflow。

而显示调用object.__setattr__就不会触发Local内部的__setattr__,从而避免上述情况。而且两者的效果是一样的,object.__setattr__的第一个参数是self,也就是这个实例,所以并不用担心是不是在父类定义了一个公共属性。

类似的还有使用object.__getattribute__的情况,一般也是为了避免无限递归。