LRDPRDX
LRDPRDX

Reputation: 682

How to leave member function undetermined until creation of an object in Python?

I have a class Node which should contain an activation function. But what activation function it will be must be determined at the moment of creation of an object using kwargs. Like so,

n1 = Node(activation='name_of_activation function')

I have working example, but I do not know if I missing something. This is my code:

import math


def Signum(x):
    return 1 if x > 0 else 0 

def Sigmoid(x):
    return math.tanh(x) 

def Sin(x):
    return math.sin(x)


class Node():
    '''  
    This is class of one node

    Each node contains an activation function.
    '''  
    def __init__(self, **kwargs):
        #possible functions
        self.__functions = { 'sgn' : Signum, 'sigmoid' : Sigmoid, 'sin' : Sin }
        self.__activate = self.__functions[kwargs.get('activation', Sigmoid)]                                       

     def Activation(self, input_value):
         return self.__activate(input_value)

n1 = Node(activation='sgn')
n2 = Node(activation='sigmoid')
n3 = Node(activation='sin')
print n1.Activation(-1), n2.Activation(-1), n3.Activation(-1)

I do not know if it is right to do what I want in this manner, i.e. it happens that I have two references to one function: self.__activate and Activation. But I do not know how to get rid of it because:

  1. On the one hand, I want to use key-value principle for declaration an object.
  2. On the other hand, it needs to be possible to call method outside of class.

Question: How to leave the activation function undetermined until moment of declaration of an object at which it determined by kwarg? Also, it needs to be possible to call the activation function outside class.

Upvotes: 0

Views: 54

Answers (2)

Dotan
Dotan

Reputation: 7622

You can pass the function itself as a parameter

class Node:

    def __init__(self, func)
         self.activation = func

then when you do Node(func).activation() it will run func.

I think it's better than passing the function name as a parameter, which is more error prone

Upvotes: 1

Netwave
Netwave

Reputation: 42756

You can actually just pass the function itself, so your class will be independant of the activation function:

def Signum(x):
    return 1 if x > 0 else 0 

def Sigmoid(x):
    return math.tanh(x) 

def Sin(x):
    return math.sin(x)


class Node():
    '''  
    This is class of one node

    Each node contains an activation function.
    '''  
    def __init__(self, activation=Sigmoid):
        #possible functions
        self.__activate = activation                                       

     def Activation(self, input_value):
         return self.__activate(input_value)

This way your class will use Sigmoid by default, also notice that you can check if the activation function is a callable:

    def __init__(self, activation=Sigmoid):
        #possible functions
        if not callable(actvation):
            raise ValueError("activation should be a callable function")
        self.__activate = activation 

If you truly need to pass the function in the kwargs just check if the key you need is in there:

    def __init__(self, **kwargs):
        #possible functions
        activation = None
        if "activation" in kwargs:
            activation = kwargs["activation"]
        if not callable(actvation):
            raise ValueError("activation should be a callable function")
        self.__activate = activation 

Upvotes: 1

Related Questions