Showing posts with label invocation. Show all posts
Showing posts with label invocation. Show all posts

Tuesday, February 10, 2009

The best way to call Python methods

What is the best way to invoke behaviour on objects in Python? Is there any better way than simply invoking a method which defines behaviour for a given instance? Or, given a class method, does the same principle not apply?

I would say it depends how you are using the instances or the classes. In the majority of cases, an instance is created, and some behaviour is invoked from that instance. However, the invoking code doesn't always know what behaviour is supported by the instance. For instance, consider the following example.
#Example; testing is a method is callable.

class MyClass:
def do_something(self):
print 'Doing something...'

def do_something(obj):
if hasattr(obj, 'do_something') and callable(obj.do_something):
obj.do_something()

if __name__=="__main__":
do_something(MyClass())

Here, we have a simple class, MyClass, that will "do something". We also have a function that will "do something". The purpose of the do_something() function is to accept some object as a parameter and invoke the "do something" behaviour on that object.

The problem I'm interested in here is that the do_something() function has no way of knowing for sure that it will be able to "do something" with the provided instance. It is the responsibility of the do_something() function to determine the invoking capability of the instance.

Now, what if we take the responsibility of know the invoking capabilities of the instance away from the do_something() function and gave it to the MyClass class? For example.
#Example; testing is a method is callable.

class MyClass:
def _do_something(self):
print 'Doing something...'
do_something=property(_do_something)

def do_something(obj):
try:
obj.do_something
except AttributeError:
pass

if __name__=="__main__":
do_something(MyClass())

In this example, obj.do_something is a managed attribute instead of a method. The do_something() function no longer needs to test the invoking capabilities of the provided instance. However, more responsibility has been added to MyClass.

Which solution is better? It depends. If our system were simple and we only needed managed attributes for all instances passed to do_something(), the latter approach may simplify things. I think in the majority of cases, the first approach offers more flexibility.

Thursday, August 21, 2008

The invoke once principle

I often come across code in a method or function definition that will use another function or method invocation to return some value. This invocation is then used more than once throughout the body of code in question. This is done because the value returned by the method is used in this new context.

The problem is, this probably isn't very efficient. Function or methods that return a value should only be invoked once in a particular context. This is usually done at or near the beginning of the code we are writing. We invoke the function or method and assign the return value to a meaningful variable name which is then used throughout the rest of the method we are developing.

This is useful when the code we are developing has no effect on the state of the value returned by the function or method invocation. There are same scenarios when invocation is necessary every time the value is needed. This is seldom the case but it does happen.

The general idea behind this principle is to avoid method invocation wherever possible. If we only need to initialize a value once in our code and there is no chance of our code disrupting the value's state, than this is the way to go.