python装饰器
python装饰器
装饰器本质上是一个Python函数(该函数的参数是一个函数,返回值也是一个函数),它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。它经常用于有切面需求的场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景。装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量与函数功能本身无关的雷同代码并继续重用。
装饰器用于性能测试
使用函数编写装饰器
import time
def log_time(func):
def _log(*args, **kwargs):
starttime = time.time()
res = func(*args, **kwargs)
print('use time: {}'.format(time.time() - starttime))
return res
return _log
@log_time
def my_func():
time.sleep(2)
my_func()
使用类编写装饰器
import time
class LogTime:
def __call__(self, func):
def _log(*args, **kwargs):
starttime = time.time()
res = func(*args, **kwargs)
print('use time: {}'.format(time.time() - starttime))
return res
return _log
@LogTime()
def my_func():
time.sleep(2)
my_func()
装饰器用于权限校验
使用函数编写装饰器
account = {
"is_authenticated":False,# 用户登录了就把这个改成True
"username":"purple", # 假装这是DB里存的用户信息
"password":"123456" # 假装这是DB里存的用户信息
}
def login(func):
def _login(*args, **kwargs):
if account["is_authenticated"] is False:
user = input('user:')
password = input('password:')
if user == account["username"] and password == account["password"]:
print("welcome %s" % user)
account["is_authenticated"] = True
else:
print("wrong username or password!")
if account["is_authenticated"]:
func(*args, **kwargs)
return _login
@login
def sichuan():
print("sichuan region.")
sichuan()
如何给装饰器增加参数?
使用类装饰器比较方便实现装饰器参数
import time
class LogTimeParams:
def __init__(self, use_int = False):
self.use_int = use_int
def __call__(self, func):
def _log(*args, **kwargs):
starttime = time.time()
res = func(*args, **kwargs)
if self.use_int:
print('use time: {}'.format(int(time.time() - starttime)))
else:
print('use time: {}'.format(time.time() - starttime))
return res
return _log
@LogTimeParams(True)
def my_func():
time.sleep(2)
my_func()
打印函数名及参数的装饰器
import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print('call %s():' % func.__name__)
print('args = {}'.format(*args))
return func(*args, **kwargs)
return wrapper
@log
def test(p):
print(test.__name__ + " param: " + p)
test("I'm a param")