attribute save restore

Steven Bethard steven.bethard at gmail.com
Fri Apr 13 15:35:40 EDT 2007


Carl K wrote:
> Is there a more elegant way of coding this:
> 
> x=o.p  # save .p
> o.p=0
> o.m()
> o.p=x  # restore .p
> 
> seems very push/pop to me - like there should be a way that doesn't need 
> a var (x) or the save/set lines should be done in one command.

With the appropriate context manger, you could write this as::

     with setting(o, 'p', 2):
         o.m()

Here's the code::

     >>> from __future__ import with_statement
     >>> @contextlib.contextmanager
     ... def setting(obj, name, value):
     ...     old_value = getattr(obj, name)
     ...     setattr(obj, name, value)
     ...     try:
     ...         yield obj
     ...     finally:
     ...         setattr(obj, name, old_value)
     ...
     >>> class C(object):
     ...     def __init__(self, x):
     ...         self.x = x
     ...     def m(self):
     ...         print self.x
     ...
     >>> c = C(1)
     >>> with setting(c, 'x', 2):
     ...     c.m()
     ...
     2
     >>> print c.x
     1

Of course, that just wraps up the same push/pop behavior you're doing 
into a context manager.

> (personally I think .m would better be implemented by passing in a 
> parameter, but that isn't my choice.)

Yep, that's the right answer. You should complain to whoever created 
this API.

STeVe



More information about the Python-list mailing list