Replacing base class

A

Alexey Klimkin

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
 
D

DH

Alexey said:
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.
 
S

Scott David Daniels

Alexey said:
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.
 
P

Peter Otten

Alexey said:
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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top