Search code examples
pythonclass-method

Deciding which class method to be called according to class initiatiation parameters


I struggled to create a descriptive title, but my challenge is the following:

In my Python application, I have a communication module which previously just used one transport type, serial. Now I also want it to include another transport layer, called RTT. My class COM contains methods like connect, send, read, log etc. Now I need two different versions of all these methods, and I want have it so that which methods being called is decided upon class instantiation.

E.g comlink = COM('RTT') will use the set of send, read, connect which is specific to the RTT protocol and vice versa, without the need of creating an extra class and decide which class to use on a higher level.

Is this possible?


Solution

  • Given I fully support @Hannes Ovrén's comment and answer, here is another way to do it

    class A():
        def __init__(self, protocol='SERIAL'):
            std_f = ('connect', 'send', 'read', 'log')
            protocols = ('RTT', 'SERIAL')
            if protocol not in protocols:
                print("Protocol not supported!")
                raise Exception # your exception here
    
            prot_f = [getattr(self, name+'_'+protocol.lower()) for name in std_f]
            for f, new_f in zip(std_f, prot_f):
                setattr(self, f, new_f)
    
        def connect_serial(self, hostname):
            print('I am serial connect', hostname)
        def send_serial(self, hostname):
            print('I am serial send', hostname)
        def read_serial(self, hostname):
            print('I am serial read', hostname)
        def log_serial(self, hostname):
            print('I am serial log', hostname)
    
        def connect_rtt(self, hostname):
            print('I am RTT connect', hostname)
        def send_rtt(self, hostname):
            print('I am RTT send', hostname)
        def read_rtt(self, hostname):
            print('I am RTT read', hostname)
        def log_rtt(self, hostname):
            print('I am RTT log', hostname)
    

    Basically it assigns the name of the standard functions when the class is instantiated, based on the given protocol

    >>> from two_types_of_methods import A
    >>> a=A('RTT')
    >>> a.connect('myserv.com')
    I am RTT connect myserv.com
    >>> a.send('myserv.com')
    I am RTT send myserv.com
    >>> a.read('myserv.com')
    I am RTT read myserv.com
    >>> a.log('myserv.com')
    I am RTT log myserv.com
    >>> b=A()
    >>> b.connect('myserv.com')
    I am serial connect myserv.com
    >>> b.send('myserv.com')
    I am serial send myserv.com
    >>> b.read('myserv.com')
    I am serial read myserv.com
    >>> b.log('myserv.com')
    I am serial log myserv.com