attribute save restore

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Carl K

    #1

    attribute save restore

    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.

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

    Carl K
  • Steven Bethard

    #2
    Re: attribute save restore

    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.c ontextmanager
    ... 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

    Comment

    • Carsten Haese

      #3
      Re: attribute save restore

      On Fri, 2007-04-13 at 14:08 -0500, 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
      In Python 2.5, you could leverage the new "with" statement with a
      properly crafted context manager along these lines:

      """
      from __future__ import with_statement

      class TempAttrSetter( object):
      def __init__(self, obj, **attrs):
      self.obj = obj
      self.attrs = attrs

      def __enter__(self) :
      self.saved_attr s = {}
      for attr, newval in self.attrs.iter items():
      self.saved_attr s[attr] = getattr(self.ob j, attr)
      setattr(self.ob j, attr, newval)

      def __exit__(self, *args):
      for attr in self.saved_attr s.keys():
      setattr(self.ob j, attr, self.saved_attr s[attr])

      class Bag(object): pass
      b = Bag()
      b.x = 1

      print b.x # prints 1
      with TempAttrSetter( b, x=3):
      print b.x # prints 3
      print b.x # prints 1
      """

      -Carsten


      Comment

      • Carl K

        #4
        Re: attribute save restore

        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.c ontextmanager
        ... 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

        Comment

        • Bruno Desthuilliers

          #5
          Re: attribute save restore

          Carl K a écrit :
          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.
          >
          (personally I think .m would better be implemented by passing in a
          parameter, but that isn't my choice.)
          I was about to comment on this. It looks like o.m is wanting to take an
          optional arg defaulting to o.p, and you should probably propose a patch
          to the author.

          My 2 cents

          Comment

          Working...