Skip to Content
I was as usual bragging about Python and coaxing one of my colleagues to try it. But he said that he does not like scripting languages because there aren’t IDEs which support intellisense and all the bells and whistles that strongly typed languages support. I was trying to make him understand that the dynamism of python makes up for the type safety net. I do not want to talk about all the extra goodies that you get with scripting languages as it is has been discussed elsewhere. I wanted to present a convincing case of Python’s dynamic nature and came up with an example that I thought was worth sharing with the community as well.  Python is the only language where I get to code working right the very first time. Anyways, here it goes. I took up the example of tracing method calls. Suppose you would like to trace a call for every method and recording statistics like the start time, end time and the execution time in milliseconds, doing this for every method in a C# or Java object would involve instrumenting the code (easy way) or to set up some complicated proxy object which involves careful design and coding. Instead it can be easily achieved using python.  Consider a business class which has the following methods. ”’businesslibrary.py – contains all the business classes”’ class BusinessClass(object):     def function1(self):         ”’Does some important business function”’         print ‘hello from function1′      def function2(self,name):         ”’Does some important business function”’         print ‘hello from’,name  Now let us write a logger helper module. ”’loggerhelper.py – the voodoo to automagically transform objects”’ import time tstampformat=’%Y%m%d-%H%M%S’ def logger(function):     def logfn(*args):         start=time.time()         print ‘starting function %s at %s’%(function.func_name,time.strftime(tstampformat,time.localtime(start)))         function(*args)         end=time.time()         print ‘ending function %s at %s’%(function.func_name,time.strftime(tstampformat,time.localtime(end)))         print ‘total processing time of the function %s took %.2f secs’%(function.func_name,(end-start))     return logfn  def attachlogger(obj):     for member in dir(obj):         if(callable(getattr(obj,member)) and not member.startswith(‘_’)):             setattr(obj,member,logger(getattr(obj,member)))   Now let us write our test script. ”’testscript.py – we test our business class here”’ from businesslibrary import BusinessClass import loggerhelper  busobj=BusinessClass() loggerhelper.attachlogger(busobj) busobj.function1() busobj.function2(‘vagmi’)  This is what it prints.  starting function function1 at 20060926-160101 hello from function1 ending function function1 at 20060926-160101 total processing time of the function function1 took 0.00 secs starting function function2 at 20060926-160101 hello from vagmi ending function function2 at 20060926-160101 total processing time of the function function2 took 0.00 secs  There you have it. A scalable tracing module in about 17 lines of code. Why would anyone not want to use python? 🙂
To report this post you need to login first.

4 Comments

You must be Logged on to comment or reply to a post.

  1. Your assertion that a tracer such as the one you have shown can’t be done elegantly in C# and Java is based on nothing but ignorance, much like most of the other Python hype I hear.

    You can achieve a much more robust, readable, and consistent “tracer” using Aspect Oriented Programming or AOP. The de-facto standard of AOP is Java’s AspectJ, and C# similarly has PostSharp.

    And it will take less lines of code than your Python sample.

    In fact, a tracing ASPECT is usually presented as the first trivial example of using AOP.

    I encourage you to google for AspectJ to learn more. There’s a lot more to AOP than tracing aspects.

    Heck, the PostSharp site even has a tutorial video explaining their tracing aspect, here:
    http://www.postsharp.org/documentation/simple-trace-aspect-tutorial/

    AOP is a more disciplined approach to “weaving” code than the usual Python paradigm of “anyone can inject whatever code they want into unsuspecting objects at anytime for whatever reason”. 

    One of the main problems with Python is that it encourages you to hack together code injection techniques, and these hacks are far less discoverable or maintainable than the Java\C# alternatives.

    Sorry to burst your bubble.

    (BTW, there are probably also AOP libraries for Python you could use).

    (0) 
    1. I agree. The python/ruby voodoo does seem scary in the beginning. But it comes in very handy to hide complexity while creating DSLs. Ruby’s Rake build tool is an excellent example of how the complicated Ruby language almost disappears to give way to a DSL.. I am aware of AspectJ. But I believe that PostSharp has a much cleaner implementation of aspects.

      There are AOP libraries in python. But they are not very popular as most people use modules and mixins to achieve the same effect. The ruby language has better support for these than Python. There were only two lines added to the python file. One to include the module and other to change the object.

      My intention was not to say python is better than all other programming languages. But each one has its merits and demerits. Languages such as Python and Ruby help us create DSLs that can significantly reduce the amount of code that we write in strongly typed languages.

      (0) 

Leave a Reply