<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def format( self, format_string, module=None, param_dict=None, force_composite=False, attr_getter=None, ):
 """ Format a string, substituting place holders which can be found in param_dict, attributes of the supplied module, or provided via calls to the attr_getter function. """

        # fix python 2 unicode issues
        if python2 and isinstance(format_string, str):
            format_string = format_string.decode("utf-8")

        if param_dict is None:
            param_dict = {}

        # if the processed format string is not in the cache then create it.
        if format_string not in self.block_cache:
            self.build_block(format_string)

        first_block = self.block_cache[format_string]

        def get_parameter(key):
            """
            function that finds and returns the value for a placeholder.
            """
            if key in param_dict:
                # was a supplied parameter
                param = param_dict.get(key)
            elif module and hasattr(module, key):
                param = getattr(module, key)
                if hasattr(param, "__call__"):
                    # we don't allow module methods
                    raise Exception()
            elif attr_getter:
                # get value from attr_getter function
                try:
                    param = attr_getter(key)
                except:  # noqa e722
                    raise Exception()
            else:
                raise Exception()
            if isinstance(param, Composite):
                if param.text():
                    param = param.copy()
                else:
                    param = u""
            elif python2 and isinstance(param, str):
                param = param.decode("utf-8")
            return param

        # render our processed format
        valid, output = first_block.render(get_parameter, module)

        # clean things up a little
        if isinstance(output, list):
            output = Composite(output)
        if not output:
            if force_composite:
                output = Composite()
            else:
                output = ""

        return output