In Python, what are some examples when decorators greatly simplify the task?

Trying to find examples of when decorators can be really useful, and when not so much. Sample code is evaluated.

+5
source share
5 answers

The easiest way to understand the usefulness of decorators is to see a few examples. Here is one, for example:

Suppose you are studying some kind of code and want to understand when and how a function is called. You can use the decorator to change the function, so it prints some debugging information each time the function is called:

import functools
def trace(f):
    '''This decorator shows how the function was called'''
    @functools.wraps(f)
    def wrapper(*arg,**kw):            
        arg_str=','.join(['%r'%a for a in arg]+['%s=%s'%(key,kw[key]) for key in kw])
        print "%s(%s)" % (f.__name__, arg_str)
        return f(*arg, **kw)
    return wrapper

@trace
def foo(*args):
    pass


for n in range(3):
    foo(n)

prints:

# foo(0)
# foo(1)
# foo(2)

If you only wanted to trace one function foo, you could, of course, add the code more simply to the definition foo:

def foo(*args):
    print('foo({0})'.format(args))

, , , .

. .

+4

- , , , . IOW,

@mydecorator
def f(...):
  # body of f

def f(...):
  # body of f
f = mydecorator(f)

, ( f ;-) def ( class, ), . , !

(, , , , ;-). ,

@classmethod
def f(cls, ...):

( )

@property
def foo(self, ...):

( 2.6 ;-), ( "" , ... , ! -).

Python, - , . , ( [[ , , , ]]) . , - DRY, "Do not Repeat Yourself", , , , .

+8

@property :

@property
def count(self):
    return self._events

:

def _get_count(self):
    return self._events

count = property(_get_count)
+4

API AppEngine @login_required decorator, :

class MyPage(webapp.RequestHandler):
    @login_required
    def get(self):
        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write("Hello, world!")

:

class MyPage(webapp.RequestHandler):
    def get(self):
        user = users.get_current_user()
        if not user:
            return self.redirect(users.create_login_url(self.request.uri))

        self.response.headers['Content-Type'] = 'text/plain'
        self.response.out.write("Hello, world!")

, , @classmethod , @staticmethod ( ) @property . , , ,

class Bar(object):
    @classmethod
    def foo(cls):
        return id(cls)

:

class Bar(object):
    def foo(cls):
        return id(cls)
    foo = classmethod(foo)

.

+1

, , "" " " " " " ".

  • - , . - .
  • , , , . , " " " "

, ( ) , .

:

  • Logging. .
  • . .
  • ( memoizing). Net Present Value , , .
  • , "@classmethod" " "
  • , " , .
  • , , .
  • ... .

http://wiki.python.org/moin/PythonDecoratorLibrary ( wiki) dectools (http://pypi.python.org/pypi/dectools) .

+1

All Articles