Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to make every Class Method call a specified method before execution?

Tags:

python

I want to make my Python Class behave in such a way that when any Class method is called a default method is executed first without explicitly specifying this in the called Class. An example may help :)

Class animals:
    def _internalMethod():
        self.respires = True

    def cat():
        self._internalMethod()
        self.name = 'cat'

    def dog():
        self._internalMethod()
        self.name = 'dog'

I want _internalMethod() to be called automatically when any method is called from an instance of animals, rather than stating it explicitly in the def of each method. Is there an elegant way to do this?

Cheers,

like image 692
chris Avatar asked Jun 08 '10 15:06

chris


1 Answers

You could use a metaclass and getattribute to decorate all methods dynamically (if you are using Python 2, be sure to subclass from object!).

Another option is just to have a fixup on the class, like:

def add_method_call(func, method_name):
    def replacement(self, *args, **kw):
        getattr(self, method_name)()
        return func(self, *args, **kw)
    return replacement

def change_all_attrs(cls, added_method):
    for method_name in dir(cls):
        attr = getattr(cls, method_name)
        if callable(attr):
            setattr(cls, method_name, add_method_call(attr, added_method))

class animals(object):
    ...

change_all_attrs(animals, '_internalMethod')

This is kind of sloppy, dir() won't get any methods in superclasses, and you might catch properties and other objects you don't intend to due to the simple callable(attr) test. But it might work fine for you.

If using Python 2.7+ you can use a class decorator instead of calling change_all_attrs after creating the class, but the effect is the same (except you'll have to rewrite change_all_attrs to make it a decorator).

like image 91
Ian Bicking Avatar answered Sep 30 '22 12:09

Ian Bicking