python 函数装饰器例子

#! coding=utf-8

#装饰器

'''
经常被用于有切面需求的场景,较为经典的有插入日志、性能测试、事务处理等。装饰器是解决这类问题的绝佳设计,
有了装饰器,我们就可以抽离出大量函数中与函数功能本身无关的雷同代码并继续重用。概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。
'''


import time

def timeit(func):
    def wrapper(a):
        start = time.clock()
        func(1,2)
        end =time.clock()
        print 'used:', end - start
        print a

    return wrapper

@timeit   #  foo = timeit(foo)完全等价, 使用之后,foo函数就变了,相当于是wrapper了
def foo(a,b):
    pass


#不带参数的装饰器
# wraper 将fn进行装饰,return wraper ,返回的wraper 就是装饰之后的fn
def test(func):
    def wraper():
        print "test start"
        func()
        print "end start"
    return wraper

@test
def foo():
    print "in foo"
foo()
"""
输出:
test start

in foo
end start
"""


#装饰器修饰带参数的函数
def parameter_test(func):
    def wraper(a):
        print "test start"
        func(a)
        print "end start"
    return wraper

@parameter_test
def parameter_foo(a):
    print "parameter_foo:"+a

#parameter_foo('hello')

"""
输出
>>>
test start

parameter_foo:hello
end start
"""


#装饰器修饰不确定参数个数的函数
def much_test(func):
    def wraper(*args, **kwargs):
        print "test start"
        func(*args, **kwargs)
        print "end start"
    return wraper

@much_test
def much1(a):
    print a

@much_test
def much2(a,b,c,d ):
    print a,b,c,d

much1('a')
much2(1,2,3,4)
"""
输出
test start
a
end start
test start
1 2 3 4
end start
"""


#带参数的装饰器   ,再包一层就可以了

def tp(name,age):
    def much_test(func):
        print 'in much_test'
        def wraper(*args, **kwargs):
            print "test start"
            print str(name),'at:'+str(age)
            func(*args, **kwargs)
            print "end start"
        return wraper
    return much_test

@tp('one','10')
def tpTest(parameter):
    print parameter
tpTest('python....')
"""
输出
in much_test
test start
one at:10
python....
end start
"""



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()






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

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)