Python 2.4 Decorators

by Phillip Eby



Listing One



(a)

import atexit



def goodbye():

    print "Goodbye, world!"



atexit.register(goodbye)



(b)

import atexit



@atexit.register

def goodbye():

    print "Goodbye, world!"





Listing Two



(a)

class Something(object):

    def someMethod(cls,foo,bar):

        print "I'm a class method"

    someMethod = classmethod(someMethod)



(b)

class Something(object):

    @classmethod

    def someMethod(cls,foo,bar):

        print "I'm a class method"





Listing Three



(a)

def mydecorator(func):

    print "decorating", func

    return func

print "before definition"

@mydecorator



def some_function():

    print "I'm never called, so you'll never see this message"

print "after definition"



(b)

before definition

decorating <function some_function at 0x00A933C0>

after definition





Listing Four



def stupid_decorator(func):

    return "Hello, world!"

@stupid_decorator

def does_nothing():

    print "I'm never called, so you'll never see this message"

print does_nothing





Listing Five



class traced:

    def __init__(self,func):

        self.func = func



    def __call__(__self,*__args,**__kw):

        print "entering", __self.func

        try:

            return __self.func(*__args,**__kw)

        finally:

            print "exiting", __self.func

@traced

def hello():

    print "Hello, world!"

hello()





Listing Six



class SomeClass(object):

    @classmethod

    @traced

    def someMethod(cls):

        print "Called with class", cls

Something.someMethod()





Listing Seven



def traced(func):

    def wrapper(*__args,**__kw):

        print "entering", func

        try:

            return func(*__args,**__kw)

        finally:

            print "exiting", func

    return wrapper





Listing Eight



def require(expr):

    def decorator(func):

        def wrapper(*__args,**__kw):

            assert eval(expr),"Precondition failed"

            return func(*__args,**__kw)

        return wrapper

    return decorator

@require("len(__args)==1")

def test(*args):

    print args[0]

test("Hello world!")





Listing Nine



def author(author_name):

    def decorator(func):

        func.author_name = author_name

        return func

    return decorator



@author("Lemony Snicket")

def sequenceOf(unfortunate_events):

    pass

print sequenceOf.author_name    # prints "Lemony Snicket"





Listing Ten



def require(expr):

    def decorator(func):

        def wrapper(*__args,**__kw):

            assert eval(expr),"Precondition failed"

            return func(*__args,**__kw)

        wrapper.__name__ = func.__name__

        wrapper.__dict__ = func.__dict__

        wrapper.__doc__ = func.__doc__

        return wrapper

    return decorator





Listing Eleven



def synchronized(func):

    def wrapper(self,*__args,**__kw):

        try:

            rlock = self._sync_lock

        except AttributeError:

            from threading import RLock

            rlock = self.__dict__.setdefault('_sync_lock',RLock())

        rlock.acquire()

        try:

            return func(self,*__args,**__kw)

        finally:

            rlock.release()

    wrapper.__name__ = func.__name__

    wrapper.__dict__ = func.__dict__

    wrapper.__doc__ = func.__doc__

    return wrapper

class SomeClass:

    """Example usage"""

    @synchronized

    def doSomething(self,someParam):

        """This method can only be entered

           by one thread at a time"""







