python装饰器

转自http://www.cnblogs.com/rhcad/archive/2011/12/21/2295507.html

第一步:最简单的函数,准备附加额外功能

[root@python day4]# cat dec1.py 
#!/usr/bin/env python

def myfunc():
	print "myfunc() called."

myfunc()

第二步:使用装饰函数在函数执行前和执行后分别附加额外功能

[root@python day4]# cat dec1.py 
#!/usr/bin/env python

def myfunc():
	print "myfunc() called."

def deco(func):
	print "beforce myfunc() called."
	func()
	print "after mufunc() called."
	return func

myfunc = deco(myfunc)
myfunc()

#执行结果
[root@python day4]# python dec1.py 
beforce myfunc() called.
myfunc() called.
after mufunc() called.
myfunc() called.

第三步:使用语法糖@来装饰函数

#!/usr/bin/env python

def deco(func):                                #定义好装饰器
	print "beforce myfunc() called."
	func()
	print "after mufunc() called."
	return func


@deco        #引用装饰器
def myfunc():
	print "myfunc() called."


myfunc()

#执行结果
[root@python day4]# python dec1.py 
beforce myfunc() called.
myfunc() called.
after mufunc() called.
myfunc() called.

第四步:使用内嵌包装函数来确保每次新函数都被调用

[root@python day4]# cat dec1.py 
#!/usr/bin/env python

def deco(func):
	def _deco():
		print "before myfunc() called."
		func()
		print "after myfunc() called."
	return _deco

@deco
def myfunc():
	print "myfunc called."
	return "ok"

myfunc()

#执行结果
[root@python day4]# python dec1.py 
before myfunc() called.
myfunc called.
after myfunc() called.

第五步:对带参数的函数进行装饰

[root@python day4]# cat dec1.py 
#!/usr/bin/env python

def deco(func):
	def _deco(a,b):
		print "before myfunc() called."
		ret = func(a,b)
		print "after mufunc() called. result: %s" % ret
		return ret
	return _deco

@deco
def myfunc(a,b):
	print "myfunc(%s,%s) called." % (a,b)
	return a + b

myfunc(3,4)

#执行结果
[root@python day4]# python dec1.py 
before myfunc() called.
myfunc(3,4) called.
after mufunc() called. result: 7

第六步:对参数数量不确定的函数进行装饰

[root@python day4]# cat dec2.py 
#!/usr/bin/env python

def deco(func):
	def _deco(*args,**kwargs):
		print "before %s called." % func.__name__
		ret = func(*args,**kwargs)
		print "after %s called. result: %s" % (func.__name__,ret)
		return ret
	return _deco

@deco
def myfunc(a,b):
	print "myfunc(%s,%s) called." % (a,b)
	return a + b

@deco
def myfunc2(a,b,c):
	print "myfunc2(%s,%s,%s) called." % (a,b,c)
	return a + b + c

myfunc(1,2)
myfunc2(3,4,5)

#执行结果
[root@python day4]# python dec2.py 
before myfunc called.
myfunc(1,2) called.
after myfunc called. result: 3
before myfunc2 called.
myfunc2(3,4,5) called.
after myfunc2 called. result: 12

第七步:让装饰器带参数

[root@python day4]# cat dec3.py 
#!/usr/bin/env python

def deco(arg):
    def _deco(func):
        def __deco():
            print("before %s called [%s]." % (func.__name__, arg))
            func()
            print("  after %s called [%s]." % (func.__name__, arg))
        return __deco
    return _deco
 
@deco("mymodule")
def myfunc():
    print(" myfunc() called.")
 
@deco("module2")
def myfunc2():
    print(" myfunc2() called.")
 
myfunc()
myfunc2()
[root@python day4]# python dec3.py 
before myfunc called [mymodule].
 myfunc() called.
  after myfunc called [mymodule].
before myfunc2 called [module2].
 myfunc2() called.
  after myfunc2 called [module2].

第八步:让装饰器带 类 参数

class locker:
    def __init__(self):
        print("locker.__init__() should be not called.")
         
    @staticmethod
    def acquire():
        print("locker.acquire() called.(这是静态方法)")
         
    @staticmethod
    def release():
        print("  locker.release() called.(不需要对象实例)")
 
def deco(cls):
    '''cls 必须实现acquire和release静态方法'''
    def _deco(func):
        def __deco():
            print("before %s called [%s]." % (func.__name__, cls))
            cls.acquire()
            try:
                return func()
            finally:
                cls.release()
        return __deco
    return _deco
 
@deco(locker)
def myfunc():
    print(" myfunc() called.")
 
myfunc()
myfunc()

第九步:装饰器带类参数,并分拆公共类到其他py文件中,同时演示了对一个函数应用多个装饰器

class mylocker:
    def __init__(self):
        print("mylocker.__init__() called.")
         
    @staticmethod
    def acquire():
        print("mylocker.acquire() called.")
         
    @staticmethod
    def unlock():
        print("  mylocker.unlock() called.")
 
class lockerex(mylocker):
    @staticmethod
    def acquire():
        print("lockerex.acquire() called.")
         
    @staticmethod
    def unlock():
        print("  lockerex.unlock() called.")
 
def lockhelper(cls):
    '''cls 必须实现acquire和release静态方法'''
    def _deco(func):
        def __deco(*args, **kwargs):
            print("before %s called." % func.__name__)
            cls.acquire()
            try:
                return func(*args, **kwargs)
            finally:
                cls.unlock()
        return __deco
    return _deco
    
    
# -*- coding:gbk -*-
'''示例9: 装饰器带类参数,并分拆公共类到其他py文件中
同时演示了对一个函数应用多个装饰器'''
 
from mylocker import *
 
class example:
    @lockhelper(mylocker)
    def myfunc(self):
        print(" myfunc() called.")
 
    @lockhelper(mylocker)
    @lockhelper(lockerex)
    def myfunc2(self, a, b):
        print(" myfunc2() called.")
        return a + b
 
if __name__=="__main__":
    a = example()
    a.myfunc()
    print(a.myfunc())
    print(a.myfunc2(1, 2))
    print(a.myfunc2(3, 4))


你可能感兴趣的:(Python装饰器)