装饰器¶
装饰器是由函数去生成的,用于装饰某个函数或者方法或者类,他可以让这个函数在执行之前或者执行之后做一些操作
实例¶
定义一个函数func
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
def func(arg):
print(arg)
func("Hello World!")
执行脚本,输出的结果为
Hello World!
现在,要在执行func
这个函数前后执行一些操作,就可以创建一个装饰器来实现
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
# 创建一个装饰器函数,接受的参数arg参数就是func函数名
def decorator(func):
def inner(*args,**kwargs):
print("before exec func: ")
ret = func(*args,**kwargs)
print("after exec func: ")
return ret
return inner
# 如果要让某个函数使用装饰器,只需要在这个函数上面加上@装饰器名字
@decorator
def func(arg):
print(arg)
func("Hello World!")
输出结果
before exec func:
Hello World!
after exec func:
实例2
import time
def timer(func):
def deco():
start_time = time.time()
func()
stop_time = time.time()
print('the func run time is %s' % (stop_time - start_time))
return deco
@timer
def test1():
time.sleep(3)
print('test1')
# @timer
# def test2(name):
# print("test:", name)
test1()
# test2()
把注释内容取消注释, 会报错, 这是因为这个装饰器不支持参数, 后文会讲到带参数的装饰器.
多个装饰器装饰同一个函数¶
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
def decorator1(func):
def inner():
print("decorator1 >>> start")
ret = func()
print("decorator1 >>> end")
return ret
return inner
def decorator2(func):
def inner():
print("decorator2 >>> start...")
ret = func()
print("decorator2 >>> end...")
return ret
return inner
@decorator1
@decorator2
def index():
print("执行函数...")
index()
执行结果
➜ python_test python3 015-exercise-3.py
decorator1 >>> start
decorator2 >>> start...
执行函数...
decorator2 >>> end...
decorator1 >>> end
更多实例¶
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
"""
函数装饰器
"""
def decorator(func):
def wrapped(*args,**kwargs):
return func(*args,**kwargs)
return wrapped
@decorator
def func(a,b):
return a + b
print(func(1,2))
"""
类装饰器
"""
class decorator:
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
return self.func(*args,**kwargs)
@decorator
def func(a,b):
return a + b
print(func(1,2))
"""
带参数的函数装饰器
"""
def parameter(a,b):
print(a,b)
def decorator(func):
def wrapped(*args,**kwargs):
return func(*args,**kwargs)
return wrapped
return decorator
@parameter(1,2)
def func(a,b):
return a + b
print(func(10,20))
"""
带参数的类装饰器
"""
def parameter(a,b):
print(a + b)
class decorator:
def __init__(self,func):
self.func = func
def __call__(self,*args,**kwargs):
return self.func(*args,**kwargs)
return decorator
@parameter(1,2)
def func(a,b):
return a + b
print(func(10,20))
"""
带参数的类装饰器
"""
def parameter(a,b):
print(a,b)
def decorator(cls):
class wrapped:
def __init__(self,*args,**kwargs):
self.cls = cls(*args,**kwargs)
def __getattr__(self,item):
return getattr(self.cls,item)
return wrapped
return decorator
@parameter(1,2)
class CLS:
def __init__(self):
self.a = 'a'
def P(self,v):
print(v)
obj = CLS()
print(obj.a)
obj.P('Hello')
"""
为函数中和类中的方法添加装饰器
"""
def Call(aClass):
calls = 0
def onCall(*args,**kwargs):
nonlocal calls
calls +=1
print('call %s to %s' % (calls,func.__name__))
return aClass(*args,**kwargs)
return onCall
@Call
def func(a,b):
return a + b
print(func(1,2))
class CLS:
def __init__(self):
self.a = 'a'
@Call
def b(self):
return self.a
obj = CLS()
print(obj.b())
执行结果
➜ python_test python3 015-exercise-4.py
3
3
1 2
30
3
30
1 2
a
Hello
call 1 to onCall
3
call 1 to onCall
a