Search code examples
pythoncall

Variable function calling in Python


Let Instrument be a class with three functions piano(self), guitar(self) and trumpet(self). The class has also a play(self) function, which will call the proper method, according to the instrument that is represented in the class.

Is there a way, with only one class Instrument (i.e., no other abstract class), to define the method that should be invoked when calling the play method?

In other words, is there a way to do the following:

my_piano = Instrument(piano)
my_piano.play() # calls piano(self) method

my_guitar = Instrument(guitar)
my_guitar.play() # calls guitar(self) method

my_trumpet = Instrument(trumpet)
my_trumpet.play() # calls trumpet(self) method

A rather simple way of doing it, but not very code clean, is to put a variable in the constructor, and then put a lot of conditions in the play method, like this:

def Instrument(object):
    def __init__(self, instrument_type):
        self.instrument_type = instrument_type

    def play(self):
        if instrument_type == 0:
            self.piano()
        elif instrument_type == 1:
            self.guitar()
        elif instrument_type == 2:
            self.trumpet()

The proper way of doing it would be to have an Instrumentclass and then three Piano, Guitar and Trumpet classes which inherit from Instrument. But for the need I have, that would be complicate things for not much.

EDIT

As requested, I explain my actual problem, which is almost identical. I have a class ComputeSth that can use five different methods to compute that something. It can compute it in ways a(self), b(self), ..., f(self). For exampple, sometimes I want to compute according to a, some other times according to c. That is easy if I just do:

my_computer = ComputeSth()
my_computer.a()
my_computer.c()

But then I noticed that in order to easily use this class in other parts of my code, I would prefer to do my_computer.compute(). So, I thought it would be convenient to construct the instance with the actual method to compute when calling compute(self). I didn't want to write five other classes, since they really wouldn't represent five different objects, but rather five ways of doing the same. I can't pass the function a,...,f as an input of the constructor because the require the self.
In other words, same as the example with Instrument, but with less "real world inheritance".


Solution

  • This is what polymorphism is for

    class Instrument:
    
      def play(self):
        pass
    
    class Guitar(Instrument):
    
      def play(self):
        print 'brau dau'
    
    class Drum(Instrument):
    
      def play(self):
        print 'dum dum'
    
    
    guitar = Guitar()
    guitar.play()
    
    drum = Drum()
    drum.play()