Lazy Initialization

Step 3: Lazy Initialization

Constructing the real service might itself be expensive, opening a connection, loading a file, warming a pool. If a proxy is created but never used, that cost is wasted. A lazy (or virtual) proxy defers building the real object until the first call actually needs it.

Change the proxy so it is constructed with the raw backend (a dict), not a ready-made RealService. Keep a slot self._real that starts as None. Only on the first fetch do you build the RealService; every later fetch reuses it.

  • Proxy._ensure_real(), build the RealService from the stored backend the first time, and only the first time

Caching from Step 2 stays. The proof: right after construction, self._real is None; the first fetch makes it real.

Hints
Starter code
class RealService:
    def __init__(self, backend):
        self.backend = dict(backend)
        self.calls = 0

    def fetch(self, key):
        self.calls += 1
        return self.backend.get(key)


class Proxy:
    def __init__(self, backend):
        self._backend = dict(backend)
        self._real = None
        self._cache = {}

    def _ensure_real(self):
        """Build self._real from self._backend on first use only."""
        # TODO: if self._real is None: self._real = RealService(self._backend)
        pass

    def fetch(self, key):
        if key in self._cache:
            return self._cache[key]
        self._ensure_real()
        value = self._real.fetch(key)
        self._cache[key] = value
        return value
Write it on a laptop

The editor and the test runner need a wide screen. Open this page on a desktop browser and your progress will be waiting.