Python装饰器学习(补充)

一、装饰函数和方法

1.对不带参数的函数进行装饰

'''对不带参数的函数进行装饰 deco1.py'''



def deco(func):

    def _deco():

        print('before %s() called.' % func.__name__)

        func()

        print('after %s() called.' % func.__name__)

    return _deco



# myFunc = deco(myFunc)

@deco

def myFunc():

    print('myFunc() called.')



myFunc()

myFunc()

运行结果:

before myFunc() called.

myFunc() called.

after myFunc() called.

before myFunc() called.

myFunc() called.

after myFunc() called.

2.对带参数的函数进行装饰

'''对带参数的函数进行装饰 deco2.py'''



def deco(func):

    def _deco(a, b):

        print('before %s() called.' % func.__name__)

        re = func(a, b)

        print('after %s() called. result: %s' % (func.__name__, re))

        return re

    return _deco



@deco

def myFunc(x, y):

    print('myFunc(%s, %s) called.' % (x, y))

    return x + y



print(myFunc(2, 8))

print(myFunc(9, 9))

运行结果:

before myFunc() called.

myFunc(2, 8) called.

after myFunc() called. result: 10

10

before myFunc() called.

myFunc(9, 9) called.

after myFunc() called. result: 18

18

3.对有可变参数的函数进行装饰

'''对有可变参数的函数进行装饰 deco3.py'''



def deco(func):

    def _deco(*args, **kwargs):

        print('before %s() called.' % func.__name__)

        re = func(*args, **kwargs)

        print('after %s() called. result: %s' % (func.__name__, re))

        return re

    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(2, 8)

myFunc(9, 9)

myFunc2(1, 2, 3)

myFunc2(4, 5, 6)

运行结果:

before myFunc() called.

myFunc(2, 8) called.

after myFunc() called. result: 10

before myFunc() called.

myFunc(9, 9) called.

after myFunc() called. result: 18

before myFunc2() called.

myFunc2(1, 2, 3) called.

after myFunc2() called. result: 6

before myFunc2() called.

myFunc2(4, 5, 6) called.

after myFunc2() called. result: 15

4.带参数的装饰器

'''带参数的装饰器 deco4.py'''



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') #myFunc = deco('myModule')(myFunc)

def myFunc():

    print('myFunc() called.')



@deco('myModule2')

def myFunc2():

    print('myFunc2() called.')



myFunc()

myFunc2()

运行结果:

before myFunc called [myModule].

myFunc() called.

after myFunc called [myModule].

before myFunc2 called [myModule2].

myFunc2() called.

after myFunc2 called [myModule2].

5.带类参数的装饰器

'''带类参数的装饰器 deco5.py'''

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) #myFunc = deco(locker)(myFunc)

def myFunc():

    print('myFunc() called.')



myFunc()

myFunc()

运行结果:

before myFunc called [<class '__main__.locker'>].

locker.acquire() called.(这是静态方法)

myFunc() called.

locker.release() called.(不需要对象实例)

before myFunc called [<class '__main__.locker'>].

locker.acquire() called.(这是静态方法)

myFunc() called.

locker.release() called.(不需要对象实例)

6.带类参数的装饰器,对一个函数应用多个装饰器

 1 '''装饰器公共类 deco6.py'''

 2 

 3 class mylocker:

 4     def __init__(self):

 5         print('mylocker.__init__() called.')

 6 

 7     @staticmethod

 8     def acquire():

 9         print('mylocker.acquire() called.')

10 

11     @staticmethod

12     def release():

13         print('mylocker.release() called.')

14 

15 class lockerex(mylocker):

16     @staticmethod

17     def acquire():

18         print('lockerex.acquire() called.')

19 

20     @staticmethod

21     def release():

22         print('lockerex.release() called.')

23 

24 def lockhelper(cls):

25     '''cls必须实现acquire和release静态方法'''

26     def _deco(func):

27         def __deco(*args, **kwargs):

28             print('before %s called. [%s]' % (func.__name__, cls))

29             cls.acquire()

30             try:

31                 return func(*args, **kwargs)

32             finally:

33                 cls.release()

34         return __deco

35     return _deco
 1 '''测试一个函数对应多个装饰器 deco6.py'''

 2 from deco6 import *

 3 

 4 class example:

 5     #myFunc = lockhelper(mylocker)(myFunc)

 6     @lockhelper(mylocker)

 7     def myFunc(self):

 8         print('myFunc() called.')

 9 

10     #myFunc2 = lockhelper(mylocker)(lockhelper(lockerex)(myFunc2))

11     @lockhelper(mylocker)

12     @lockhelper(lockerex)

13     def myFunc2(self, a, b):

14         print('myFunc2() called.')

15         return a + b

16 

17 if __name__ == '__main__':

18     a = example()

19     a.myFunc()

20     print(a.myFunc())

21     print('============================')

22     print(a.myFunc2(1, 2))

23     print(a.myFunc2(3, 5))

运行结果:

before myFunc called. [<class 'deco6.mylocker'>]

mylocker.acquire() called.

myFunc() called.

mylocker.release() called.

before myFunc called. [<class 'deco6.mylocker'>]

mylocker.acquire() called.

myFunc() called.

mylocker.release() called.

None

============================

before __deco called. [<class 'deco6.mylocker'>]

mylocker.acquire() called.

before myFunc2 called. [<class 'deco6.lockerex'>]

lockerex.acquire() called.

myFunc2() called.

lockerex.release() called.

mylocker.release() called.

3

before __deco called. [<class 'deco6.mylocker'>]

mylocker.acquire() called.

before myFunc2 called. [<class 'deco6.lockerex'>]

lockerex.acquire() called.

myFunc2() called.

lockerex.release() called.

mylocker.release() called.

8

二、装饰类

以上的例子中,装饰器接收一个函数,并返回一个函数,从而起到加工函数的效果(装饰器(如deco中)新建了一个可调用对象(如_deco),在其中添加了新增的功能print,通过调用原有函数return myFunc()来实现原有函数的功能,最后将新建的调用对象返回return _deco)。

在Python 2.6以后,装饰器被拓展到类。一个装饰器可以接收一个类,并返回一个类,从而起到加工类的效果。

def deco(aClass):

    class newClass:

        def __init__(self, age):

            self.total_display = 0

            self.wrapped = aClass(age)

        def display(self):

            self.total_display += 1 # 记录display方法的调用次数

            print('total display', self.total_display)

            self.wrapped.display()

    return newClass



@deco # Bird = deco(Bird)

class Bird:

    def __init__(self, age):

        self.age = age

    def display(self):

        print('My age is', self.age)



b = Bird(5)

for i in range(3):

    b.display()

运行结果:

total display 1

My age is 5

total display 2

My age is 5

total display 3

My age is 5

 

你可能感兴趣的:(python)