函数:修饰器
定义一个函数,叫做process_data,用来模拟处理数据,需要耗时3-5秒. 我们在项目的各处都调用了这个函数.
def process_data():
time.sleep(random.randint(3,5))
现在我们需要看一下函数调用开始时的时间, 和调用结束时的时间. 类似下面这样. OK, 搞定了.
def process_data():
print "start porcess data", time.time()
time.sleep(random.randint(3,5))
print "porcess data done!", time.time()
但是, 现在又有一个函数也需要打印开始和结束时间. 然后又有两个!
我们不会在每一个函数里面添加这两个, 我们需要一个更好的办法.
来看一下用修饰器怎么实现. 我们只需要在每一个函数前面加一个 @print_time 就可以了.
程序看起来更加清晰明了,意义明确.
import random
import time
def print_time(func):
def inner():
print "start porcess data", time.time()
func()
print "porcess data done!", time.time()
return inner
@print_time
def process_data():
"""定义一个函数,模拟处理数据,需要耗时3-5秒."""
time.sleep(random.randint(3, 5))
process_data()
process_data()
process_data()
发生了什么事情?
其实, 函数前面添加修饰器, 相当于:
process_data = print_time(process_data)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import time
def print_time(func):
def inner():
print "start porcess data", time.time()
func()
print "porcess data done!", time.time()
return inner
def process_data():
"""定义一个函数,模拟处理数据,需要耗时3-5秒."""
time.sleep(random.randint(3, 5))
process_data = print_time(process_data)
process_data()
process_data()
process_data()
来一个更复杂的例子
我们在porcess_data的时候启用缓存, 如果缓存过期了, 我们需要重要加载数据到缓存.(都是模拟的..), 另外也需要打印开始和结束时间.
有哪些新东西:
- 函数有多个修饰器.
- 修饰器也有参数了.
- 修饰器中把args, kargs传递到内层的函数
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import time
last_update_time = None
def print_time(func):
def inner(*args, **kargs):
print "start porcess data", time.time()
func(*args, **kargs)
print "porcess data done!", time.time()
return inner
def update_data():
global last_update_time
print "data expired; update it"
last_update_time = time.time()
def use_cache(expire_time=30*60):
def wrapper(func):
if last_update_time is None or time.time() - last_update_time > expire_time:
update_data()
def inner(*args, **kargs):
func(*args, **kargs)
return inner
return wrapper
@use_cache(5*60)
@print_time
def process_data(*args, **kargs):
"""定义一个函数,模拟处理数据,需要耗时3-5秒."""
time.sleep(random.randint(3, 5))
process_data()
process_data()
process_data()
又发生了什么
process_data = use_cache(5*60)(process_data)