Replacing base class

Discussion in 'Python' started by Alexey Klimkin, Mar 3, 2004.

  1. Hello!

    Is it possible in python to replace base class with another one?

    Assume an example:
    class A:
    def f(self):
    print 'A'
    class B(A):
    def f(self):
    A.f(self)
    print 'B'
    class C:
    def f(self):
    print 'C'

    I need to make class Bm with the same functionality as B, but
    derived from C, instead of A. Classes C and A have the same
    interface.

    The call of f() for Bm should output:
    C
    B

    As you see, the main problem is B.f, since it uses f() from base
    class. Any clues?

    Regards,
    Alexey
     
    Alexey Klimkin, Mar 3, 2004
    #1
    1. Advertising

  2. Alexey Klimkin

    DH Guest

    Alexey Klimkin wrote:
    > Hello!
    >
    > Is it possible in python to replace base class with another one?
    >
    > Assume an example:
    > class A:
    > def f(self):
    > print 'A'
    > class B(A):
    > def f(self):
    > A.f(self)
    > print 'B'
    > class C:
    > def f(self):
    > print 'C'
    >
    > I need to make class Bm with the same functionality as B, but
    > derived from C, instead of A. Classes C and A have the same
    > interface.
    >
    > The call of f() for Bm should output:
    > C
    > B
    >
    > As you see, the main problem is B.f, since it uses f() from base
    > class. Any clues?
    >


    You might want to give some more details about what you are really
    doing, because there are multiple ways to do this, but the simplest is
    to just replace A.f(self) with:
    super(B,self).f(self)
    And make your classes subclass "object" so they are new style classes
    (required for "super" to work).

    Another option is to make "B" a mixin class that can work with A or C or
    both:
    class B: #mixin
    def f(self):
    for base in self.__class__.__bases__:
    if (base is not B) and hasattr(base,"f"):
    base.f(self)
    print 'B'
    class Test(B,C,A): pass #put mixin class first

    But you might also want to create an "interface" class that specifies
    the "f" method, which A & C "implement".
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/164901
    http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/204349
    http://peak.telecommunity.com/PyProtocols.html

    Then in B, you could call f() on all bases that implement that interface
    if you liked.
     
    DH, Mar 3, 2004
    #2
    1. Advertising

  3. Alexey Klimkin wrote:

    > Hello!
    >
    > Is it possible in python to replace base class with another one?

    I am not certain what you are asking here. If you use new-style
    classes, and I'm correct about what you want, try:

    > class A:

    -> class A(object):
    > def f(self):
    > print 'A'
    > class B(A):
    > def f(self):
    > A.f(self)

    -> super(B, self).f() # or super(B).f(self) if you prefer
    > print 'B'
    > class C:

    -> class C(object):
    > def f(self):
    > print 'C'


    > ... Any clues?

    Hope this is a clue.

    --
    -Scott David Daniels
     
    Scott David Daniels, Mar 3, 2004
    #3
  4. Alexey Klimkin

    Peter Otten Guest

    Alexey Klimkin wrote:

    > Assume an example:
    > class A:
    > def f(self):
    > print 'A'
    > class B(A):
    > def f(self):
    > A.f(self)
    > print 'B'
    > class C:
    > def f(self):
    > print 'C'
    >
    > I need to make class Bm with the same functionality as B, but
    > derived from C, instead of A. Classes C and A have the same
    > interface.


    Maybe the following pattern could be helpful:

    class Abstract(object):
    """ define the interface with noops """
    def f(self):
    pass

    class A(Abstract):
    def f(self):
    super(A, self).f()
    print "A",

    class B(Abstract):
    def f(self):
    super(B, self).f()
    print "B",

    class C(Abstract):
    def f(self):
    super(C, self).f()
    print "C",


    You can now make classes that derive from any combination of A, B and C,
    where the method f() in each of the bases is invoked exactly once, e. g:

    def demo(b):
    print b.__class__.__bases__
    b.f()
    print

    for B1 in (A, B, C):
    for B2 in (A, B, C):
    if B1 != B2:
    class B3(B1, B2):
    pass
    demo(B3())

    class B3(A, B, C):
    pass

    demo(B3())

    The disadvantage is the need of the base class (Abstract in the example)
    where the common interface is defined and which seems somewhat unnatural in
    Python.

    Peter
     
    Peter Otten, Mar 3, 2004
    #4
    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. tomek
    Replies:
    2
    Views:
    681
    Andrey Tarasevich
    Dec 1, 2003
  2. Alf P. Steinbach
    Replies:
    6
    Views:
    550
    John Carson
    Sep 3, 2005
  3. Hicham Mouline
    Replies:
    1
    Views:
    596
    Victor Bazarov
    Apr 20, 2009
  4. Rob Meade

    Replacing - and not Replacing...

    Rob Meade, Apr 5, 2005, in forum: ASP General
    Replies:
    5
    Views:
    282
    Chris Hohmann
    Apr 11, 2005
  5. Karan Rajput
    Replies:
    2
    Views:
    146
    Abinoam Jr.
    Dec 22, 2010
Loading...

Share This Page