Python - 装饰器

1. 装饰器的示例1

参考:

Fluent_Python的笔记,http://www.cnblogs.com/allen2333/p/8848010.html

装饰器本质上就是一个python函数,他可以让其他函数在不需要做任何代码变动的前提下,增加额外的功能,装饰器的返回值也是一个函数对象。(符合开闭原则)。
应用场景:比如插入日志、性能测试、事务处理、缓存、权限校验等场景。
实现: 高阶函数+函数嵌套+闭包

import functools


def wrapper(func):
    @functools.wraps(func)  # 帮助我们设置函数的元信息,注释看看。保存原函数某些信息
    def inner(*args, **kwargs):
        return func(*args, **kwargs)

    return inner


@wrapper
def f1():
    pass


@wrapper
def f2():
    pass


print(f1.__name__)
print(f2.__name__)

2. 装饰器的示例2

def timer(func):                    #装饰器
    def inner(*args,**kwargs):
        '''执行函数之前要做的'''
        ret = func(*args,**kwargs)
        '''执行函数之后要做的'''
        return ret
    return inner

@timer                               #@timmer 相当于 func = timmer(func)
def func():
    print("我是一只小小鸟")

func()                               #func() = inner()    调用装饰器
def timer(func):

    def inner(*args,**kwargs):
        print("xxx")                    #在执行前打印
        ret = func(*args,**kwargs)
        print("abc")              #在执行后打印
        return ret
    return inner

@timer
def func():
    print("我是一只小小鸟")

func()


计算结果:

xxx
我是一只小小鸟
abc

3. functools.wraps

参考:

https://segmentfault.com/a/1190000009398663
https://docs.python.org/3.6/library/functools.html#functools.wraps

wraps函数其实就是一个修饰器版的update_wrapper函数,它的功能和update_wrapper是一模一样的。
就是将被修饰的函数(wrapped) 的一些属性值赋值给 修饰器函数(wrapper)。

4. flasky中的检查权限,用装饰器实现

git reset --hard 9a。
实现了两个装饰器,一个用来检查常规权限,一个专门用来检查管理员权限。

from functools import wraps
from flask import abort
from flask_login import current_user
from .models import Permission


def permission_required(permission):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not current_user.can(permission):
                abort(403)
            return f(*args, **kwargs)
        return decorated_function
    return decorator


def admin_required(f):
    return permission_required(Permission.ADMIN)(f)
def permission_required(permission):
    def decorator(f):
        @wraps(f)
        def decorated_function(*args, **kwargs):
            if not g.current_user.can(permission):
                return forbidden('Insufficient permissions')
            return f(*args, **kwargs)
        return decorated_function
    return decorator
posted @ 2018-05-09 21:04  Rocin  阅读(132)  评论(0编辑  收藏  举报