Jonas Lindeløv
Jonas Lindeløv

Reputation: 5683

Python: Inherit/reuse specific methods from classes

I want a python class that is composed partly of specific methods from other classes which operates on self in the "composed class". How do I do that?

E.g. if I want to include specific methods from classA and classB in my new class "theClass":

    # Some classes to "inherit" from
    class classA(object):
        def methA1(self, value):
            self.attrib = value*1
        def methA2(self, value):
            self.attrib = value*2
    class classB(object):
        def methB1(self, value):
            self.attrib = value*3
        def methB2(self, value):
            self.attrib = value*4

    # The class I want to build
    class theClass(object):
        # WHAT TO DO HERE?
        # -------------------
        methA1 = classA.methA1
        methB2 = classB.methB2
        # -------------------
        # /WHAT TO DO HERE

        # add additional methods...
        def methC(self, value):
            self.attrib = value*5

    # I want the following behavior
    instance = theClass()
    instance.methB2(5)  # sets instance.attrib to 20
    instance.methA2(5)  # error, does not exist

Upvotes: 0

Views: 2522

Answers (1)

unutbu
unutbu

Reputation: 880927

You could use mixins:

class MixinA1(object):
    def methA1(self, value):
        self.attrib = value*1
class MixinB2(object):       
    def methB2(self, value):
        self.attrib = value*4
class classA(MixinA1):
    def methA2(self, value):
        self.attrib = value*2
class classB(MixinB2):
    def methB1(self, value):
        self.attrib = value*3

# The class I want to build
class theClass(MixinA1, MixinB2):
    def methC(self, value):
        self.attrib = value*5

Mixins make sense if the Mixin class encapsulates some unit of functionality which you desire to add on to multiple classes.

If the methods don't naturally break down into units of functionality, here is another alternative:

def methA1(self, value):
    self.attrib = value*1
def methA2(self, value):
    self.attrib = value*2
def methB2(self, value):
    self.attrib = value*4
def methB1(self, value):
    self.attrib = value*3
def methC(self, value):
    self.attrib = value*5

class classA(object):
    methA1 = methA1
    methA2 = methA2    
class classB(object):
    methB1 = methB1
    methB2 = methB2        
class theClass(object):
    methA1 = methA1
    methB2 = methB2
    methC = methC

This is very similar to the alternative you've already posted, except that it places except that it places all classes on an equal footing -- initially the methods are not associated with any particular class. This might be preferable so theClass is not "breaking encapsulation" by reaching in and nabbing a method from a class (such as classA) on which it does not explicitly depend.

Upvotes: 3

Related Questions