python decorator 2.Decorator with parameters 3.The best practice of decorator maybe 4.Class Decorator

The following two snippets are semantically identical

[code 1]

def deco1(func):
    print "before"
    func()
    print "after"

def func():
    print "in func"

if __name__ == '__main__':
    print "--------------"
    deco1(func)
    print "=============="

[code 2]

def deco1(func):
    def _wrap():
        print "before"
        func()
        print "after"
    return _wrap

@deco1
def func():
    print "in func"

if __name__ == '__main__':
    print "--------------"
    func()
    print "=============="

output

--------------
before
in func
after
==============

2.Decorator with parameters

The following two snippets are semantically identical

[code 3]

def deco1(receive_deco1_param):
    def _wrap(receive_function_name):
        def __wrap(receive_function_param):
            print "deco1's param is " + receive_deco1_param
            print "before"
            receive_function_name(receive_function_param)
            print "after"
        return __wrap
    return _wrap

def func(p):
    print "func's param is " + p

if __name__ == '__main__':
    print "--------------"
    deco1("deco1 param")(func)("func param")
    print "=============="

[code 4]

def deco1(receive_deco1_param):
    def _wrap(receive_function_name):
        def __wrap(receive_function_param):
            print "deco1's param is " + receive_deco1_param
            print "before"
            receive_function_name(receive_function_param)
            print "after"
        return __wrap
    return _wrap

@deco1("deco1 param")
def func(p):
    print "func's param is " + p

if __name__ == '__main__':
    print "--------------"
    func("func param")
    print "=============="

output

--------------
deco1's param is deco1 param
before
func's param is func param
after
==============

3.The best practice of decorator maybe

[code 5]

from functools import wraps

def deco1(receive_deco1_param):
    def _wrap(receive_function_name):
        @wraps(receive_function_name)
        def __wrap(receive_function_param):
            print "deco1's param is " + receive_deco1_param
            print "before"
            receive_function_name(receive_function_param)
            print "after"
        return __wrap
    return _wrap
	
@deco1("deco1 param")
def func(p):
    print "func's param is " + p

if __name__ == '__main__':
    print "--------------"
    func("func param")
    print func.__name__
    print "=============="

In code 4,if print func.__name__ in main, output will be __wrap,but in code 5,the output is func.

4.Class Decorator

The semantics and design goals of class decorators are the same as for function decorators; the only difference is that you’re decorating a class instead of a function.

[reference]

1.pep-0318