Django lazy loading and LazyObject

Log in to see the middleware, it was found request.user returns SimpleOject objects, see the LazyObject turn down, look at the source code looked a long time did not understand

Internet search a pile of inert material under load to achieve it is to understand what function, to return to see the source code, probably know the principle LazyObject implementation

Django inert load is generated when the first object is not instantiated, until the property or method call the object when instantiated operations do

LazyObject Source:

= empty Object () 


# inert implemented method of loading generic class of methods, i.e., to see whether an object is instantiated 
# if not yet instantiated, the instance of a subclass of method invocation 
# last call the original method based on the instance func generated 
DEF new_method_proxy (FUNC):
     DEF Inner (Self, * args):
         IF self._wrapped IS empty: 
            self._setup () 
        return FUNC (self._wrapped, * args)
     return Inner 


class LazyObject:
     "" " 
    A wrapper for Another class that CAN Used to Delay instantiation of BE at The 
    wrapped class. 

    By subclassing, you have have to Intercept and the ALTER at The Opportunity at The 
    instantiation. the If you do not need to do that, use SimpleLazyObject. 
    "" " 

    #. The Avoid Infinite recursion When Tracing the __init__ (# 19456) 
    _wrapped = None 

    DEF  the __init__ (Self):
         # Note: IF A subclass The overrides the __init __ (), IT Will LIKELY need to 
        # the override __copy __ () and __deepcopy __ () AS Well. 
        Self. empty = _wrapped   # flag if there is instantiated 

    __getattr__ = new_method_proxy (getattr)   # calls generic instantiation delay method 

    DEF  __setattr__ (Self, name, value):
         iF name == " _wrapped " : # the Assign to __dict__ to Avoid __setattr__ Infinite Loops.When the changes are _wrapped, special handling 
            # 
            . Self the __dict__ [ " _wrapped " ] = value
         the else :
             IF self._wrapped IS empty: 
                self._setup () 
            setattr (self._wrapped, name, value)    # instantiated, modified examples of attributes 

    DEF  __delattr__ (Self, name):
         IF name == " _wrapped " :   # can not delete _wrapped property 
            the raise (TypeError " . CAN not the delete _wrapped " )
         IF self._wrapped is empty:
            self._setup()
        delattr(self._wrapped, name)

    def _setup(self):
        """
        Must be implemented by subclasses to initialize the wrapped object.
        """
        #只可由子类调用
        raise NotImplementedError('subclasses of LazyObject must provide a _setup() method')

    # Because we have messed with __class__ below, we confuse pickle as to what
    # class we are pickling. We're going to have to initialize the wrapped
    # object to successfully pickle it, so we might as well just pickle the
    # wrapped object since they're supposed to act the same way.
    #
    # Unfortunately, if we try to simply act like the wrapped object, the ruse
    # will break down when pickle gets our id(). Thus we end up with pickle
    # thinking, in effect, that we are a distinct object from the wrapped
    # object, but with the same __dict__. This can cause problems (see #25389).
    #
    # So instead, we define our own __reduce__ method and custom unpickler. We
    # pickle the wrapped object as the unpickler's argument, so that pickle
    # will pickle it normally, and then the unpickler simply returns its
    # argument.
    def __reduce__(self):
        if self._wrapped is empty:
            self._setup()
        return (unpickle_lazyobject, (self._wrapped,))

    def __copy__(self):
        if self._wrapped is empty:
            # If uninitialized, copy the wrapper. Use type(self), not
            # self.__class__, because the latter is proxied.
            return type(self)()
        else:
            # If initialized, return a copy of the wrapped object.
            return copy.copy(self._wrapped)

    def __deepcopy__(self, memo):
        if self._wrapped is empty:
            # We have to use type(self), not self.__class__, because the
            # latter is proxied.
            result = type(self)()
            memo[id(self)] = result
            return result
        return copy.deepcopy(self._wrapped, memo)

    __bytes__ = new_method_proxy(bytes)
    __str__ = new_method_proxy(str)
    __bool__ = new_method_proxy(bool)

    # Introspection support
    __dir__ = new_method_proxy(dir)

    # Need to pretend to be the wrapped class, for the sake of objects that
    # care about this (especially in equality tests)
    __class__ = property(new_method_proxy(operator.attrgetter("__class__")))
    __eq__ = new_method_proxy(operator.eq)
    __lt__ = new_method_proxy(operator.lt)
    __gt__ = new_method_proxy(operator.gt)
    __ne__ = new_method_proxy(operator.ne)
    __hash__ = new_method_proxy(hash)

    # List/Tuple/Dictionary methods support
    __getitem__ = new_method_proxy(operator.getitem)
    __setitem__ = new_method_proxy(operator.setitem)
    __delitem__ = new_method_proxy(operator.delitem)
    __iter__ = new_method_proxy(iter)
    __len__ = new_method_proxy(len)
    __contains__ = new_method_proxy(operator.contains)

 

Guess you like

Origin www.cnblogs.com/EmptyRabbit/p/11298603.html