On Learning Python, Part 3

Now on Chapter 10 of Dive Into Python where I discover a code sample and explanation of using getattr to create what the author refers to as a "generic XML node dispatcher". It is very analagous to what I referred to in my previous post -- a Strategy Pattern.

The one difference between implementing a Strategy Pattern in C# and Python is that in C# you have a bit more overhead (at least at design time -- not sure what the performance comparison is on the precompiled C# version of this model is compared to the dynamic, interpreted, nature of Python).

You typically use a creation pattern, like a Factory, to perform some logic to determine what "type" of Strategy object to instantiate and return that implements some common interface. However, with Python, you can simply name your methods in accordance with what you expect to be able to discern from the types you are going to process and then use getattr to create the method name and execute it in and at runtime:

# Samples below taken from Example 10.18/10.19 in Dive into Python

def parse(self, node):
    parseMethod = getattr(self, "parse_%s" % node.**class-**.**name**)

def parse_Text(self, node):
    text = node.data
    if self.capitalizeNextWord:
        self.capitalizeNextWord = 0

def parse_Document(self, node):

def parse_Element(self, node):
    handlerMethod = getattr(self, "do_%s" % node.tagName)

As you can see this can be nested and used at n-levels of you different strategies (not to overuse that term in these posts).

To do this in C# you would have to use Reflection, and I am not sure that Python isn't doing something like that under the covers, but since it is a dynamic interpreted language, I would surmise that the rules are a bit different.

Either way, I am starting to see some of the powerful features of such a dynamic language.

Tags: python, getattr, strategy pattern