def __getattr__(self, attr):
        """This function reads through the layers from top to bottom
        returning the first occurrence of the requested attribute

        :param attr: An attribute name
        :type attr: string

        :returns: The value of the attribute
        :rtype: object
        """
        num_layers = len(self.layers)
        for i in reversed(xrange(num_layers)):
            obj = self.layers[i]
            if hasattr(obj, attr):
                val = getattr(self.layers[i], attr)
                if i != num_layers - 1:
                    setattr(self.layers[-1], attr, val)
                return val

        raise AttributeError("%s is not an attribute" % attr)
def __getattr__ ( self , attr ) : num_layers = len ( self . layers ) for i in reversed ( xrange ( num_layers ) ) : obj = self . layers [ i ] if hasattr ( obj , attr ) : val = getattr ( self . layers [ i ] , attr ) if i != num_layers - 1 : setattr ( self . layers [ - 1 ] , attr , val ) return val raise AttributeError ( "%s is not an attribute" % attr )
This function reads through the layers from top to bottom
        returning the first occurrence of the requested attribute

        :param attr: An attribute name
        :type attr: string

        :returns: The value of the attribute
        :rtype: object