<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 async def cache_instruments(self, require: Dict[top_types.Mount, str] = None):
 """ - Get the attached instrument on each mount and - Cache their pipette configs from pipette-config.json If specified, the require element should be a dict of mounts to instrument models describing the instruments expected to be present. This can save a subsequent of :py:attr:`attached_instruments` and also serves as the hook for the hardware simulator to decide what is attached. """

        checked_require = require or {}
        self._log.info("Updating instrument model cache")
        found = self._backend.get_attached_instruments(checked_require)
        for mount, instrument_data in found.items():
            model = instrument_data.get('model')
            if model is not None:
                p = Pipette(model,
                            self._config.instrument_offset[mount.name.lower()],
                            instrument_data['id'])
                self._attached_instruments[mount] = p
            else:
                self._attached_instruments[mount] = None
        mod_log.info("Instruments found: {}".format(
            self._attached_instruments))