Decorator descriptor pattern "observer" context manager itertools