1.函数能够赋与变量缓存
def func(message): print('Got a message: {}'.format(message)) send_message = func send_message('hello world') #输出 #Got a message: hello world
2.函数能够看成函数的参数闭包
def get_message(message): return 'Got a message: ' + message def root_call(func, message): print(func(message)) root_call(get_message, 'hello world') 输出 #Got a message: hello world
3.函数里嵌套函数app
def func(message): def get_message(message): print('Got a message: {}'.format(message)) return get_message(message) func('hello world') 输出 #Got a message: hello world
4.函数做为函数返回值(闭包)函数
def func_closure(): def get_message(message): print('Got a message: {}'.format(message)) return get_message send_message = func_closure() send_message('hello world') #输出 #Got a message: hello world
例post
def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapper def greet(): print('hello world') greet = my_decorator(greet) greet()
使用语法糖 @测试
def my_decorator(func): def wrapper(): print('wrapper of decorator') func() return wrapper @my_decorator def greet(): print('hello world') greet() # 输出 # wrapper of decorator # hello world
def my_decorator(func): def wrapper(message): print('wrapper of decorator') func(message) return wrapper @my_decorator #至关于 greet == wrapper(message) def greet(message): print(message) greet('hello world') # 输出 #wrapper of decorator #hello world
这个装饰器只能用在有一个参数的函数,若是想对任意参数的函数通用,能够这么写spa
def my_decorator(func): def wrapper(*args, **kwargs): print('wrapper of decorator') func(*args, **kwargs) return wrapper
def repeat(num): def my_decorator(func): def wrapper(*args, **kwargs): for i in range(num): print('wrapper of decorator') func(*args, **kwargs) return wrapper return my_decorator @repeat(4) def greet(message): print(message) greet('hello world') # 输出: # wrapper of decorator # hello world # wrapper of decorator # hello world # wrapper of decorator # hello world # wrapper of decorator # hello world
greet.__name__ #输出 'wrapper' help(greet) # 输出 Help on function wrapper in module __main__: wrapper(*args, **kwargs)
能够看出,原函数的原信息会被wrapper取代日志
import functools def my_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): print('wrapper of decorator') func(*args, **kwargs) return wrapper @my_decorator def greet(message): print(message) greet.__name__ # 输出 #'greet'
class Count: def __init__(self, func): self.func = func self.num_calls = 0 def __call__(self, *args, **kwargs): self.num_calls += 1 print('num of calls is: {}'.format(self.num_calls)) return self.func(*args, **kwargs) @Count def example(): print("hello world") example() # 输出 # num of calls is: 1 # hello world example() # 输出 # num of calls is: 2 # hello world
@decorator1 @decorator2 @decorator3 def func(): ... #至关于 decorator1(decorator2(decorator3(func)))
import functools def my_decorator1(func): @functools.wraps(func) def wrapper(*args, **kwargs): print('execute decorator1') func(*args, **kwargs) return wrapper def my_decorator2(func): @functools.wraps(func) def wrapper(*args, **kwargs): print('execute decorator2') func(*args, **kwargs) return wrapper @my_decorator1 @my_decorator2 def greet(message): print(message) greet('hello world') # 输出 # execute decorator1 # execute decorator2 # hello world
1)身份验证,不登陆不容许操做code
import functools def authenticate(func): @functools.wraps(func) def wrapper(*args, **kwargs): request = args[0] if check_user_logged_in(request): # 若是用户处于登陆状态 return func(*args, **kwargs) # 执行函数 post_comment() else: raise Exception('Authentication failed') return wrapper @authenticate def post_comment(request, ...) ...
2)日志记录 可测试函数的执行时间orm
import time import functools def log_execution_time(func): def wrapper(*args, **kwargs): start = time.perf_counter() res = func(*args, **kwargs) end = time.perf_counter() print('{} took {} ms'.format(func.__name__, (end - start) * 1000)) return res return wrapper @log_execution_time def calculate_similarity(items): ...
3) 合法性检测
import functools def validation_check(input): @functools.wraps(func) def wrapper(*args, **kwargs): ... # 检查输入是否合法 @validation_check def neural_network_training(param1, param2, ...): ... LRU cache. @lru_cache缓存装饰器 @lru_cache def check(param1, param2, ...) # 检查用户设备类型,版本号等等 ...
极客时间《Python核心技术与实战》专栏