We can't find the internet
Attempting to reconnect
Something went wrong!
Attempting to reconnect
← Memory, Copies and Slow Code step 15 of 38
Build a Registry That Does Not Keep Objects Alive
Build an InstanceRegistry that finds objects by a string key without
keeping them alive. The starter stores ordinary references, so an object
stays in the registry after every other part of the program has dropped
it.
registry = InstanceRegistry()
db = Resource("db")
registry.register("db", db)
registry.get("db") is db # True
del db
registry.get("db") # None, the object was freed
len(registry) # 0
What to write
register(key, obj)stores a weak reference toobj. Registering a key again replaces the old entry.get(key)returns the object, orNoneif the key was never registered or its object has been freed.len(registry)counts only the entries whose object is still alive.- If
objcannot be weakly referenced,registerraisesTypeError. Let that error reach the caller, and leave any earlier entry for that key as it was.
When you need the object, call its weak reference once, store the result
in a local, and check the local. Your code must pass mypy --strict.
The registry may keep dead weak references inside, as long as get and
len treat them as missing.
What the driver does
Keep Resource, SlottedResource and solve as they are. Resource is an
ordinary class, so it supports weak references. SlottedResource is a
dataclass with slots=True and no weakref_slot=True, so registering it
raises TypeError.
solve(register, drop, probe_slotted) creates a Resource for each key in
register and keeps the newest one for each key in a local dictionary. It
checks that get returns those exact objects. Then it drops its references
for the keys in drop and calls gc.collect(). A key that appears twice in
drop, or was never registered, changes nothing more.
The report contains:
live: the sorted, distinct registered keys whose objects are still alive.size:len(registry)at the end.identity_ok: whethergetreturned the exact objects before the driver dropped any. It isTruewhenregisteris empty.slotted_error:"TypeError"ifprobe_slottedis true and registering aSlottedResourcefailed, otherwise"".
Going further
A registry that lives for the whole program should also delete dead
entries, so that its dictionary of keys does not keep growing. A
WeakValueDictionary does that for you.
Your code, saved here
Sign in to access your accepted solutions and saved draft history. You can keep reading the lesson without an account.
Sign in to your accountStuck?
Python reference solution
Sign in to track your attempts toward unlocking the reference solution.