Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Decorators vs. classes in python web development

I've noticed three main ways Python web frameworks deal request handing: decorators, controller classes with methods for individual requests, and request classes with methods for GET/POST.

I'm curious about the virtues of these three approaches. Are there major advantages or disadvantages to any of these approaches? To fix ideas, here are three examples.

Bottle uses decorators:

@route('/')
def index():
    return 'Hello World!'

Pylons uses controller classes:

class HelloController(BaseController):
    def index(self):
        return 'Hello World'

Tornado uses request handler classes with methods for types:

 class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world")

Which style is the best practice?

like image 515
Tristan Avatar asked Jun 06 '10 16:06

Tristan


People also ask

Can Python decorators be used on classes?

Decorators are a very powerful and useful tool in Python since it allows programmers to modify the behaviour of function or class.

What is the biggest advantage of the decorator in Python?

A decorator in Python is a function that takes another function as its argument, and returns yet another function . Decorators can be extremely useful as they allow the extension of an existing function, without any modification to the original function source code.

When should I use Python decorators?

You'll use a decorator when you need to change the behavior of a function without modifying the function itself. A few good examples are when you want to add logging, test performance, perform caching, verify permissions, and so on. You can also use one when you need to run the same code on multiple functions.

What is the benefit of using a decorator Python?

Decorators in Python Python has an interesting feature called decorators to add functionality to an existing code. This is also called metaprogramming because a part of the program tries to modify another part of the program at compile time.


2 Answers

There's actually a reason for each of the three methods you listed, specific to each project.

  • Bottle tries to keep things as simple/straightforward as possible for the programmer. With decorators for routes you don't have to worry about the developer understanding OOP.
  • Pylons development goal is to make code re-usable and to be easily integrated with WSGI-style HTTP process routing. As such, they have chosen a very OOP way of organizing routes. As an example, you could copy & paste HelloController into any Pylons app and it should just magically work. Even if said app is being served up via WSGI in some complicated fashion.
  • Tornado has yet another reason for doing things the way it does: Tornado's epoll-based IOLoop (in conjunction with tornado.web.Application) instantiates each RequestHandler as requests come in. By keeping each RequestHandler limited to a specific GET or POST this allows IOLoop to quickly instantiate the class, process the request, and finally let it get garbage collected. This keeps it fast and efficient with a small memory footprint regardless of how many RequestHandlers your application has. This is also the reason why Tornado can handle so many more simultaneous requests than other Python-based web servers (each request gets its own instance).

Now, having said all that you should know that you can always override the default framework behavior. For example, I wrote a MethodDispatcher for Tornado that makes it work more like Pylons (well, I had CherryPy in mind when I wrote it). It slows down Tornado a tiny amount (and increases the memory footprint slightly) due to having one large RequestHandler (as opposed to a lot of small ones) but it can reduce the amount of code in your app and make it a little easier to read (In my biased opinion, of course =).

like image 173
Dan McDougall Avatar answered Oct 29 '22 00:10

Dan McDougall


The various frameworks are trying to achieve the best performance through the best code (for writing and reading). They each adopt different strategies based on or around MVC or MVT.

What you're focussing on will probably come down to personal taste. And so will my answer. I'm trying very hard to avoid any sort of holy war because there may be valid technical arguments that I just don't know about.

But I personally prefer to keep the routing separate from the controller (django's view) and templating separate from that. It makes reusing controllers really simple. Yeah, I'm a Django user.

As such, I'm really not a big fan of Bottle's decorators or wrapping things in great big hulking classes. I used to when I was an ASP.NET dev but Django set me free.

like image 42
Oli Avatar answered Oct 28 '22 23:10

Oli