Rebinding __setattr__

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Jan Schilleman

    Rebinding __setattr__

    Hi all,

    I am trying to redefine __setattr__.

    The base class is in a library (actually, it is
    win32com.client .DispatchBaseCl ass) and I do not want to touch it. My problem
    is exemplified below. To my surprise, __setattr__ and __str__ behave
    differently; I can redefine __str__ and the inherited __str__ is still the
    redefined one. But redefining __setattr__ on the base class does not get
    inherited. In Base.__dict__ the __setattr__ is the one I expected, but it is
    not called from B.

    What is the problem? Is __setattr__ cached somewhere [and not updated?]?

    class Base:

    def __setattr__(sel f, attr, value):
    print 'Base __setattr__'
    self.__dict__[attr] = value

    def __str__(self):
    return "Base"

    class A(Base): pass
    class B(Base): pass

    def __setattr__(sel f, attr, value):
    print 'alternative __setattr__'
    self.__dict__[attr] = value

    def __str__(self):
    return "Alternativ e"

    a = A()
    b = B()

    for i in (1, 2):
    print
    print 'run', i
    print

    print Base.__dict__
    print A.__dict__
    print B.__dict__

    print
    print 'a:', a
    a.a1 = 1

    print 'b:', b
    b.b1 = 1

    setattr(Base, '__setattr__', __setattr__)
    setattr(A, '__setattr__', __setattr__)
    setattr(Base, '__str__', __str__)
    setattr(A, '__str__', __str__)






  • Maric Michaud

    #2
    Re: Rebinding __setattr__

    Le Monday 15 September 2008 01:06:08 Jan Schilleman, vous avez écrit :
    Hi all,
    >
    I am trying to redefine __setattr__.
    >
    The base class is in a library (actually, it is
    win32com.client .DispatchBaseCl ass) and I do not want to touch it. My
    problem is exemplified below. To my surprise, __setattr__ and __str__
    behave differently; I can redefine __str__ and the inherited __str__ is
    still the redefined one. But redefining __setattr__ on the base class does
    not get inherited. In Base.__dict__ the __setattr__ is the one I expected,
    but it is not called from B.
    >
    What is the problem? Is __setattr__ cached somewhere [and not updated?]?
    >
    Yes, it doesn't work with classic classes, but do with new-style ones, I don't
    know if this an accepted behavior or not.
    Can't you use new-style classes ?

    >>>[2]: sys.version
    ...[2]: '2.5.2 (r252:60911, May 28 2008, 19:19:25) \n[GCC 4.2.4 (Debian
    4.2.4-1)]'

    >>>[64]: class A :
    def __setattr__(sel f, name, value) :
    print "A", name
    ....:
    ....:
    >>>[67]: class B(A) : pass
    ....:
    >>>[68]: A().c, B().c = 1, 2
    A c
    A c
    >>>[69]: A.__setattr__ = lambda s, n, v : sys.stdout.writ e("%s, %s, %s\n"%
    (s, n, v))
    >>>[70]: A().c, B().c = 1, 2
    <__main__.A instance at 0x2b3b41546290> , c, 1
    A c




    >>>[71]: class A(object) :
    def __setattr__(sel f, name, value) :
    print "A", name
    ....:
    ....:
    >>>[74]: class B(A) : pass
    ....:
    >>>[75]: A().c, B().c = 1, 2
    A c
    A c
    >>>[76]: A.__setattr__ = lambda s, n, v : sys.stdout.writ e("%s, %s, %s\n"%
    (s, n, v))
    >>>[77]:
    >>>[78]: A().c, B().c = 1, 2
    <__main__.A object at 0x2b3b45dfa350> , c, 1
    <__main__.B object at 0x2b3b45dfa350> , c, 2

    --
    _____________

    Maric Michaud

    Comment

    • Jan Schilleman

      #3
      Re: Rebinding __setattr__

      That still would require changing the source of the library ... And i'm not
      sure if it would have side effects.

      "Maric Michaud" <maric@aristote .infoschreef in bericht
      news:mailman.10 33.1221477203.3 487.python-list@python.org ...
      Le Monday 15 September 2008 01:06:08 Jan Schilleman, vous avez écrit :
      Hi all,
      >
      I am trying to redefine __setattr__.
      >
      The base class is in a library (actually, it is
      win32com.client .DispatchBaseCl ass) and I do not want to touch it. My
      problem is exemplified below. To my surprise, __setattr__ and __str__
      behave differently; I can redefine __str__ and the inherited __str__ is
      still the redefined one. But redefining __setattr__ on the base class does
      not get inherited. In Base.__dict__ the __setattr__ is the one I expected,
      but it is not called from B.
      >
      What is the problem? Is __setattr__ cached somewhere [and not updated?]?
      >
      Yes, it doesn't work with classic classes, but do with new-style ones, I
      don't
      know if this an accepted behavior or not.
      Can't you use new-style classes ?

      >>>[2]: sys.version
      ....[2]: '2.5.2 (r252:60911, May 28 2008, 19:19:25) \n[GCC 4.2.4 (Debian
      4.2.4-1)]'

      >>>[64]: class A :
      def __setattr__(sel f, name, value) :
      print "A", name
      ....:
      ....:
      >>>[67]: class B(A) : pass
      ....:
      >>>[68]: A().c, B().c = 1, 2
      A c
      A c
      >>>[69]: A.__setattr__ = lambda s, n, v : sys.stdout.writ e("%s, %s, %s\n" %
      (s, n, v))
      >>>[70]: A().c, B().c = 1, 2
      <__main__.A instance at 0x2b3b41546290> , c, 1
      A c




      >>>[71]: class A(object) :
      def __setattr__(sel f, name, value) :
      print "A", name
      ....:
      ....:
      >>>[74]: class B(A) : pass
      ....:
      >>>[75]: A().c, B().c = 1, 2
      A c
      A c
      >>>[76]: A.__setattr__ = lambda s, n, v : sys.stdout.writ e("%s, %s, %s\n" %
      (s, n, v))
      >>>[77]:
      >>>[78]: A().c, B().c = 1, 2
      <__main__.A object at 0x2b3b45dfa350> , c, 1
      <__main__.B object at 0x2b3b45dfa350> , c, 2

      --
      _____________

      Maric Michaud


      Comment

      Working...