Dylan Storey

Recovering academic, hacker, tinkerer, scientist.

Dynamically Placing Functions Into Python Classes

This is just me messing around with dynamically setting functions within a class. And then persisting them.

Given the class task.py:

class task(object):
  """docstring for task"""
  def __init__(self , c):
    super(task, self).__init__()
    self.variable_name = c

  def fit (self):
    None

  def transform(self):
    None

We can define class methods dynamically in foo.py:

from task import task as task
from types import MethodType

def cubic(c):
  mine = task(c)

  def ft (self,x):
    print("You passed me {}".format(x))
    self.exp = 3
    return 3 ** self.exp

  def tform(self,x):
    return x**self.exp

  mine.fit=MethodType(ft,mine)
  mine.transform = MethodType(tform,mine)
  return mine

def square(c):
  mine = task(c)

  def ft (self,x):
    print('you passed me {}'.format(x))
    self.exp = 2
    return x ** self.exp

  def tform (self,x):
    return x ** self.exp

  mine.fit = MethodType(ft,mine)
  mine.transform = MethodType(tform,mine)
  return mine

So now we can call each of these functions to get an instance of class task.

>>> squared = foo.square('square_this')
>>> squared.fit(3)
You passed me 3
9
>>>squared.transform(4)
16

>>>cubed = foo.cubic('cube_this')
>>>cubed.fit(3)
You passed me 3
27
>>>cubed.transform(4)
64

And we can do stuff like this now:

>>> processes = {cubed.variable_name : cubed.transform, squared.variable_name : squared.transform}
>>> incoming_data = {'square_this' : 2 , 'cube_this' : 3 }
>>> transformed_data = {k : processes[k](v) for k,v in incoming_data.items()}
>>> transformed_data
{'square_this': 4, 'cube_this': 27}

Even better we can do something like this:

import dill
>>> persist = dill.dumps(processes)
>>> load = dill.loads(persist)
>>> transformed_data = {k : load[k](v) for k,v in incoming_data.items()}
>>> transformed_data
{'square_this': 4, 'cube_this': 27}
blog comments powered by Disqus