装饰器介绍
装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。 它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。
制作一个装饰器
1.写一个hello world
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
def hello(func):
def wrapper():
print('Hello')
func()
return wrapper
def world():
print('World')
helloWorld = hello(world)
if __name__ == '__main__':
helloWorld()
输出
Hello
World
2.使用装饰器实现以上效果
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from functools import wraps
def hello(func):
@wraps(func) # 重写函数名字
def wrapper():
print('Hello')
return func()
return wrapper
@hello
def world():
print('World')
if __name__ == '__main__':
world()
print(world.__name__)
输出
# without @wraps(func)
Hello
World
wrapper
# with @wraps(func)
Hello
World
world
细心的你已经察觉到两者代码的相似度如此之高,装饰器本质上是语法糖。
函数带参数的装饰器
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from functools import wraps
def hello(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('Hello')
return func(*args, **kwargs)
return wrapper
@hello
def people(arg):
print(arg)
@hello
def many_people(arg1, arg2):
print(arg1)
print(arg2)
if __name__ == '__main__':
people('Jack')
many_people('Tom', 'Mary')
输出
Hello
Jack
Hello
Tom
Mary
装饰器带参数
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
from functools import wraps
def withArg(arg):
def decorator(func):
@wraps(func)
def wrapper(*args, **kwargs):
print(arg)
return func(*args, **kwargs)
return wrapper
return decorator
@withArg('Hello')
def people(arg):
print(arg)
if __name__ == '__main__':
people('Jack')
输出
Hello
Jack
类装饰器
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
class ClassDecorator:
def __init__(self, func):
print('init')
self.func = func
def __call__(self, *args, **kwargs):
self.func(self, *args, **kwargs)
print('call')
class Decorators:
name = ''
def __init__(self, name):
self.name = name
print(self.name)
@ClassDecorator
def foo(self):
print('foo')
if __name__ == '__main__':
d = Decorators('isPlaying')
d.foo()
输出
init
isPlaying
foo
call