Recursion with __setattr__

Discussion in 'Python' started by Chris Young, Oct 16, 2005.

  1. Chris Young

    Chris Young Guest

    Operating Ubunutu Linux 5.04 on iMac 333mhz
    Python 2.4.1 in IDLE 1.1.1

    In trying to create a interactive drawing framework in Python I came across
    the idea of binding attributes of one object to attributes of another.

    The way it works is when obj1.attr1 is set obj2.attr2 should have it's
    __setattr__ method called as well. But it ends up giving me a recursion error.

    The attribute synchronization is shown below:

    #file: sync.py

    def sync(attr1,obj1,obj2,attr2=None):
    """Synchronize attribute access

    attr1:
    name of attribute to synchronize
    attr2:
    (optional) attribute name to use when setting second object.
    """
    if not attr2: attr2 = attr1
    # rename old __setattr__'s
    try:
    obj1.__old_setattr__ = obj1.__setattr__
    obj2.__old_setattr__ = obj2.__setattr__
    except AttributeError: pass
    # modify mirrored attributes on attribute change
    def hook_setattr(inst):
    # Hey! Only classes have special methods!
    class sethook(inst.__class__):
    def __setattr__(self,name,value):
    try:
    self.__old_setattr__(name,value)
    except AttributeError: pass
    if name in self.__syncdict__:
    entry = self.__syncdict__[name]
    for mirror,attr in entry: pass
    # recursion error here: setattr(mirror,attr,value)
    #sethook.__name__ = inst.__class__.__name__ # magic?
    inst.__class__ = sethook
    # append synchronization info
    try:
    obj1.__syncdict__[attr1].append(obj2,attr2)
    except AttributeError:
    obj1.__syncdict__ = {attr1: [(obj2,attr2)]}
    try:
    obj2.__syncdict__[attr2].append(obj1,attr1)
    except AttributeError:
    obj2.__syncdict__ = {attr2: [(obj1,attr1)]}
    # make the magic work
    hook_setattr(obj1)
    hook_setattr(obj2)

    When I try to call this like sync('attr',obj,obj2) I get a recursion error.
    I could understand this happening if I was calling setattr on itself, but
    why the other object?

    Any help is greatly appreciated. Also, any pointers on efficiency or easier
    ways is also welcome. Thanks in
    advance.
     
    Chris Young, Oct 16, 2005
    #1
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Anand
    Replies:
    0
    Views:
    415
    Anand
    Dec 18, 2003
  2. Thomas Heller

    __getattr__, __setattr__

    Thomas Heller, Oct 20, 2005, in forum: Python
    Replies:
    3
    Views:
    683
    Thomas Heller
    Oct 20, 2005
  3. L.C. Rees
    Replies:
    3
    Views:
    391
    Scott David Daniels
    Feb 8, 2006
  4. George Sakkis
    Replies:
    7
    Views:
    311
    Facundo Batista
    Feb 27, 2007
  5. Joshua Kugler
    Replies:
    12
    Views:
    430
    Joshua Kugler
    Apr 29, 2008
Loading...

Share This Page