← Practice
πŸ“– Context managerscontext-manager-capture
LessonΒ·difficulty 3/5Β·~20 min

Context managers: build a Capture

Context managers: build a Capture

You've used with open(...) as f: a thousand times. The magic behind with is two methods on an object:

  • __enter__(self) runs when the block starts. Whatever it returns is what as binds to.
  • __exit__(self, exc_type, exc, tb) runs when the block ends β€” even if an exception was raised β€” so it's where you clean up.
python
class Greeter:
    def __enter__(self):
        self.log = []
        return self                # <- bound to `as g`
    def __exit__(self, exc_type, exc, tb):
        return False               # don't swallow exceptions

with Greeter() as g:
    g.log.append("hi")
# g.log is now ['hi']

__enter__ returning self is the common pattern: it hands the live object to the with block so you can call methods on it.

Your task

Write a class Capture that:

  • in __enter__, sets up an empty list self.items and returns self,
  • has a method add(self, x) that appends x to self.items,
  • has an __exit__(self, exc_type, exc, tb) (it can just return False).
python
with Capture() as c:
    c.add(1)
    c.add(2)
c.items        # [1, 2]

with Capture() as c:
    c.add("hello")
c.items        # ['hello']

The items attribute lives on the object, so it's still readable after the with block closes.

Tests

  • two ints
  • single string
  • nothing added
  • three mixed
  • fresh each time (hidden)

✦ Stuck? Ask for a spark

warming up
Loading editor…

$ Console output will appear here.

>_AI tutor
Sign in to chat with the tutor.