Blog Posts
Navigation
« PyQt and Drag and Drop functionality | Python @classmethod »
Monday
Dec122011

Dynamically adding methods to a class in Python

I recently found a way to dynamically create method and add it to a class.  I wanted to figure this out because I had a decent list of properties in the class that I wanted to create a "get" function for.  That way I can use a function called get(property name) for accessing that property instead of calling it directly.  However, since the list way fairly long, I didn't want to have to type out all of the functions if I could find a way to dynamically create them.  

The class had a list of properties such as:

properties = ['name', 'number', 'location']

Then, in the class, I created a fairly generic function called getPropertyValue(self, *args, **kwargs), which took an argument of the name of the property that we wanted to get the value for.  So it ended up being something like:

def getProperty(self, *args, **kwargs):
      if kwargs:
            # check to make sure we have a property argument passed in
            propertyName = kwargs.get('property', None)

            # check to make sure the property name is in the list of properties
            if propertyName in self.properties:
                  # get the value of the property and return it
                  return getattr(self, propertyName)

From there I can then create a function based off of that generic function called something like getName() dynamically.  To do this I used a for loop in the __init__ function for the class.  It ended up being:

for prop in self.properties:
      self.__dict__['get%s' % prop] = types.MethodType(pm.windows.Callback(self.getProperty,
                                                       {}, property = prop), self)

The tricky part was calling a function with an argument using MethodType. I started by trying to use a lambda function, but this does not work very well in for loops due to scope issues. Luckily I was doing this for a script in Maya, so I was able to use PyMEL which has a Callback object that solves this for me. That is what the pm.windows.Callback is, and it works well in this case since I am running this from Maya. It returns an instance of the method back to me with the proper argument set for it.

Reader Comments

There are no comments for this journal entry. To create a new comment, use the form below.

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>