attribute save restore

Carl K carl at personnelware.com
Fri Apr 13 15:47:57 EDT 2007


Steven Bethard wrote:
> 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.

Thanks.

As I was eating lunch I came up with:

x,o.p = o.p,0

Which I am pretty sure is just bad :)
I need to cut back on the hot sauce.

> 
>> (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.

Will do.  Something is buggy anyway, so as long as I am commenting...

Carl K



More information about the Python-list mailing list