您的位置:首页 > 编程语言 > Python开发

Python装饰器学习(补充)

2013-05-17 01:11 309 查看
一、装饰函数和方法

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.带类参数的装饰器,对一个函数应用多个装饰器

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

class mylocker:
def __init__(self):
print('mylocker.__init__() called.')

@staticmethod
def acquire():
print('mylocker.acquire() called.')

@staticmethod
def release():
print('mylocker.release() called.')

class lockerex(mylocker):
@staticmethod
def acquire():
print('lockerex.acquire() called.')

@staticmethod
def release():
print('lockerex.release() called.')

def lockhelper(cls):
'''cls必须实现acquire和release静态方法'''
def _deco(func):
def __deco(*args, **kwargs):
print('before %s called. [%s]' % (func.__name__, cls))
cls.acquire()
try:
return func(*args, **kwargs)
finally:
cls.release()
return __deco
return _deco


'''测试一个函数对应多个装饰器 deco6.py'''
from deco6 import *

class example:
#myFunc = lockhelper(mylocker)(myFunc)
@lockhelper(mylocker)
def myFunc(self):
print('myFunc() called.')

#myFunc2 = lockhelper(mylocker)(lockhelper(lockerex)(myFunc2))
@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('============================')
print(a.myFunc2(1, 2))
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: