Python 装饰器使用场景,注意点

闭包的定义:函数的返回值为函数对象

装饰器的定义:通过装饰器,来修改原函数的一些功能,使得原函数不需要修改,就具备需要的功能。

使用内置的装饰器@functools.wrap, 保留原函数的元信息

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)

print(greet.__name__)  # 'greet'


使用场景

常用场景:身份认证、日志记录、输入合理性检查和缓存等。

身份认证, 例如发布文章或留言的时候,判断需要登陆

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, ...)
    pass
 

日志记录常用在测试函数的执行时间

import time
import functools

def log_execution_time(func):
    @functools.wraps(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):
    ...

输入合理性检查,在大型公司的机器学习框架中,对其输入(往往很大的json文件) 进行合理性检查。

import functools

def validation_check(input):
    @functools.wraps(func)
    def wrapper(*args, **kwargs): 
        ... # 检查输入是否合法
    
@validation_check
def neural_network_training(param1, param2, ...):
    ...

缓存,Python内置LRU cache为例
(不了解LRU cache, 自行点击链接查阅)

LRU cache, 在Python 中表现形式为@lru_cache,它会缓存进程中的函数参数和结果,缓存满了会删除最久没有访问(least recently used) 的数据。

大型公司服务器代码中往往存在很多关于设备的检查,例如安卓还是iPhone,版本号。其中一个原因是,新的feature,只适用在特殊系统或版本以上才有。

这样就可以使用缓存装饰器,包裹检查函数,避免反复调用,提高程序运行效率。

@lru_cache
def check(param1, param2, ...) # 检查用户设备类型,版本号等等
    ...

你可能感兴趣的:(python)