Posts Tagged 'python'

Decorators in Python

A few days ago, I mentioned that I was going to start coding Python again. So, I was looking at Python 2.5 and one of the cooler features that I discovered first were decorators. From what I understand, a decorator wraps behavior of a function or method. It sort of reminds me of auxiliary methods in Common Lisp. A Python function or method can be decorated.

So, I created I quick example that creates a decorator. The simplest decorator is a regular function that accepts a single argument, the function that is being decorated. The decorator returns another function that accepts an argument set and an environment. This is basically a lexical closure. In my decorator, logged, the inner function wrapper is enclosed and wrapper just prints out a message:

def logged(f):
  def wrapper(*args, **kw):
    print "calling %s with args %s." % (f.func_name, args)
    try:
      return f(*args, **kw)
    finally:
      print "done calling %s" % (f.func_name)
  return wrapper

The interesting thing is that wrapper ends up calling the function object passed into the decorator. In this case, the function object is the decorated function add():

@logged
def add(n1, n2):
  return n1 + n2
print add(2, 1)
print add(4, -2)

My simple adder is decorated by the @logged syntax. The Python runtime will execute the decorator and call the closure, passing the arguments from the original function call. When I execute my test program:

$ python decorate.py
calling add with args (2, 1).
done calling add
3
calling add with args (4, -2).
done calling add
2

Awesome! Now, there is more to decorators than meets the eye, and I need to gain more experience using decorators. So, it looks like I am off to a great start.

Starting Python Again

After almost a three year break, I am starting to write some Python code again. I am experimenting on developing a RESTful part catalog web service. I last used Python when it was in version 1.5.2. I think that there have been many changes, because the page holding version 1.5.2 states quite frankly:

Do yourself a favor and get a more recent version!

Fair enough. I picked up version 2.5.1 for Windows. The install was quite painless. The most improved thing that I noticed was the revamped python.org web site. There is a lot more information now. I find this quite refreshing. I should have no trouble picking it up again.

So, why did I pick Python? Well, it was a tough decision. For the most part, Python was the right tool for this job. It was a written in a language that I am somewhat familiar with, it is portable, and gave the flexibility that I needed. I love other languages, but I found that the others did not quite fit the mold. For example:

  • I rejected Java right away because Java would take a lot more time that C/C++ in my case. The language is certainly as good as C#, but I am not as familiar with it as Python or C/C++. Additionally, the core framework is significantly larger than I remember. Like Python, Java has added features since inception. I have not touched Java in about eight years, so my learning curve will be very high. Today, there seems to be a lot better tools and frameworks to have ease the development pains, but it is not enough for me to give Java consideration.
  • I use C# and ASP.NET for my day job, so why did I not pick them? Frankly, it is damn tough to make a truly RESTful web service in ASP.NET. ASP.NET likes SOAP web services. Forcing ASP.NET to do a RESTful web service is like fitting a square peg in a round hole while having a root canal. In retrospect, it’s a blessing in disguise to me, because I prefer to use open source tools anyway. I do not want to give the impression of bias. I honestly did try to make it happen fairly recently. It was just not meant to be. Again, the tool was not right for this job.
  • C/C++ requires more investment in time. I have been programming in C family for years. I love it for it’s speed of execution and it is right against the metal. If I was creating Unix tools where execution speed is critical, C/C++ will be my absolute first choice. However, the compile cycles and the debugging become a deal killer for a web prototype. When I am rapid prototyping, I have a need for development speed, rather than saving a few cycles. Like many other high-level languages, Python still gives me many options to integrate and optimize using C/C++. So, if I need it, I will use this feature.
  • What about Lisp? I’ve coded a lot of Lisp for other applications and experiments. I have been writing a lot about Lisp in this blog. It was my second language that I learned.  So, it would be natural for me to just use Lisp, right? Well, not in this case.  Most likely, the code for this experiment will be sent to other developers.  They are more likely to be receptive to Python than Lisp.  There I said it.  I still believe that Lisp is the best language out there. But, being the best language is not the only reason to use it. Sometimes, you need to give in for the greater good.
  • Ruby and it’s poster child framework, Ruby on Rails, came a very close second. I said that my choice in Python was a tough decision. I like the Rails framework.  Rails is very RESTful.  I was blown away when I first encountered it.  The framework make development easy.  So, why did Python win?  Again, I am more familiar with Python than Ruby…and that is it. Python has a similar framework to Rails, called TurboGears. I give props to the Ruby clan to developing a great framework. It is so innovative that many languages have came up with clones.  So, it boils down to language familiarity.  Python won by a nose.

So, there you have it.  I picked Python for this project.  Hopefully, it won’t let me down. I’ll try to keep regular updates for everyone who is interested.