Object-based inheritance in Python

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Tobias Windeln

    Object-based inheritance in Python

    Hi!

    I'm looking for suggestions on object-based inheritance
    in Python. Automatic forwarding (often called delegation)
    in Python is easy:

    def __getattr__(sel f, attr):
    return getattr(self.de legatee, attr)
    def __setattr__(sel f, attr, value):
    return setattr(self.de legatee, attr, value)

    Maybe there is a way to hand over self to the delegatee object.
    So the next call on self in the delegatee object is send to the child
    object.

    A small example:

    class Child:
    def __init__(self, delegatee):
    self.__dict__['delegatee'] = delegatee

    # TODO ... delegation/overriding mechanism ....

    def m(self):
    self.m2(self)
    def m3(self):
    print("Child")

    class Delegatee:
    def m2(self):
    self.m3(self)
    def m3(self):
    print("Child")

    #______________ _________
    [color=blue][color=green][color=darkred]
    >>> c = Child(Delegatee ())
    >>> c.m()[/color][/color][/color]
    Child[color=blue][color=green][color=darkred]
    >>>[/color][/color][/color]

    The call to m2() is forwarded to the Delegatee.
    The call to m3() in m2() is redirected to Child and
    the m3() Method in Child is called:
    =============== =============== =============== ========
    m2(child_self)
    child --------------------> delegatee
    |
    <-------------------|
    m3(child_self)
    =============== =============== =============== ========

    This functionality would be helpfull in Patterns (Decorator, Strategy, etc.)

    Do you have any suggestions on how to hand over self to the delegatee?
    Since the first argument of every method in Python is self, the rest of
    the object-based inheritance works automatically!

    I usually work with Java, where I implemented this functionality with
    enormous effort. When I saw Pythons reflective capabilities (__getattr__
    etc.) I wondered if this is possible in an generic/easy way.


    Thanks in advance
    Tobias

  • Stephan Diehl

    #2
    Re: Object-based inheritance in Python

    Tobias Windeln wrote:
    [color=blue]
    > Hi!
    >
    > I'm looking for suggestions on object-based inheritance
    > in Python. Automatic forwarding (often called delegation)
    > in Python is easy:
    >[/color]

    Have a look at Hans Nowaks 'selfish' implementation:


    This is a pythonesque interpretation of the 'self' language by Sun.
    By the way, if you are googling, you want probably look for 'prototype based
    languages'.

    Comment

    • Alexander Schmolck

      #3
      Re: Object-based inheritance in Python

      Tobias Windeln <Tobias.Windeln @gmx.de> writes:
      [color=blue]
      > Maybe there is a way to hand over self to the delegatee object.[/color]
      [...]
      [color=blue]
      > class Child:
      > def __init__(self, delegatee):
      > self.__dict__['delegatee'] = delegatee[/color]

      Can't you just use this pattern:

      self.__dict__['delegatee'] = delegatee(self)
      ?

      'as

      Comment

      • Tobias Windeln

        #4
        Re: Object-based inheritance in Python

        Stephan Diehl wrote:[color=blue]
        > Tobias Windeln wrote:
        >
        >[color=green]
        >>Hi!
        >>
        >>I'm looking for suggestions on object-based inheritance
        >>in Python. Automatic forwarding (often called delegation)
        >>in Python is easy:
        >>[/color]
        >
        >
        > Have a look at Hans Nowaks 'selfish' implementation:
        > http://zephyrfalcon.org/download/selfish-0.4.2.zip[/color]

        Thanks, this was exactly what I was looking for.

        Comment

        • Tobias Windeln

          #5
          Re: Object-based inheritance in Python

          Alexander Schmolck wrote:
          [color=blue]
          > Tobias Windeln <Tobias.Windeln @gmx.de> writes:
          >
          >[color=green]
          >>Maybe there is a way to hand over self to the delegatee object.[/color]
          >
          > [...]
          >
          >[color=green]
          >>class Child:
          >> def __init__(self, delegatee):
          >> self.__dict__['delegatee'] = delegatee[/color]
          >
          >
          > Can't you just use this pattern:
          >
          > self.__dict__['delegatee'] = delegatee(self)[/color]

          This results in:
          AttributeError: Delegatee instance has no __call__ method


          Here is the solution by Hans Nowaks
          (http://zephyrfalcon.org/download/selfish-0.4.2.zip):

          ############### ############### ############### ############### ######

          import new
          import types

          __version__ = "0.4.2"
          __author__ = "Hans Nowak"
          __license__ = "python"
          __cvsid__ = "$Id: selfish_v2.py,v 1.3 2003/09/22 04:30:50 hansn Exp $"

          def rebind(method, obj):
          return new.instancemet hod(method.im_f unc, obj, obj.__class__)

          class SelfObject:

          def __init__(self):
          pass

          def __setattr__(sel f, name, value):
          if name.endswith(" _p"):
          assert isinstance(valu e, SelfObject), \
          "Only SelfObjects can be used for inheritance"
          if isinstance(valu e, types.FunctionT ype):
          m = new.instancemet hod(value, self, self.__class__)
          self.__dict__[name] = m
          elif isinstance(valu e, types.UnboundMe thodType):
          self.__dict__[name] = rebind(value, self)
          elif isinstance(valu e, types.MethodTyp e):
          self.__dict__[name] = rebind(value, self)
          else:
          self.__dict__[name] = value

          def __getattr__(sel f, name):
          if name in self.__dict__.k eys():
          # seems superfluous; if the attribute exists, __getattr__
          # isn't called
          return self.__dict__[name]
          else:
          # scan "ancestors" for this name...
          # left-right based on name, depth first
          items = self.__dict__.i tems()
          items.sort()
          for attrname, obj in items:
          if attrname.endswi th("_p"):
          try:
          z = obj.__getattr__ (name)
          except AttributeError:
          pass
          else:
          if isinstance(z, types.MethodTyp e):
          z = rebind(z, self)
          return z
          raise AttributeError, name

          Object = SelfObject()

          Comment

          • Hung Jung Lu

            #6
            Re: Object-based inheritance in Python

            Stephan Diehl <stephan.diehlN OSPAM@gmx.net> wrote in message news:<btm4mo$qp t$06$1@news.t-online.com>...[color=blue]
            > Tobias Windeln wrote:[color=green]
            > >
            > > I'm looking for suggestions on object-based inheritance
            > > in Python. Automatic forwarding (often called delegation)
            > > in Python is easy:
            > >[/color]
            >
            > Have a look at Hans Nowaks 'selfish' implementation:
            > http://zephyrfalcon.org/download/selfish-0.4.2.zip
            >
            > This is a pythonesque interpretation of the 'self' language by Sun.
            > By the way, if you are googling, you want probably look for 'prototype based
            > languages'.[/color]

            Seems like prototype-based languages are catching up the attention of
            people. I have looked at them recently. My feeling is that somehow
            main development stopped around 1997. I have looked at Io (I know it's
            born in 2002, but the ideas come from before), but I just get the
            feeling that Io is not "clean" enough. Anyway, I think that instead of
            designing final languages, it's a better idea to make *prototype*
            languages (sorry for the pun) and experiment with various features.
            One problem I've seen in Io is that they started to write software,
            when the language itself is not well-defined yet. And so, you make
            changes to the language, and you have to make corrections to large
            body of existing code. And, also, once too much code is written with
            existing language, it becomes really hard to make language changes
            later: too much work to update legacy packages.

            There are a few problems with current programming languages that only
            come to bite you at large scale projects (Multiple Inheritance,
            Metaprogramming , AOP, Multiple Version handling,
            Transactional/Incremental programming with real-time rollback/undo,
            ideas from Functional languages, etc.) And my experience has been that
            the more complex your project becomes, the more you wish you had a
            simple, clean, solid, powerful theoretical foundation for your
            programming language. Prototype-based seems the right direction to go,
            but I am kind of disappointed at all existing prototype-based
            languages out there. Somehow something happened in 1997 that stopped
            research in this direction. And now the prototype-based languages seem
            so much behind. It's like time has been frozen for 6 years.

            regards,

            Hung Jung

            Comment

            Working...