python 装饰器 (列举flask 框架路由装饰器 和 django源码装饰器,和常见的装饰器)五种装饰器带你飞

python装饰器可以在不改变原有函数代码的基础上,实现一些新功能的加入,是python开发的一大神器。

下面结合我自身的学习经历列举一些常见的装饰器,以供大家借鉴参考:

0 通用装饰器

特点:

functools.wraps 装饰参数func后,装饰器生成的新test函数可保留自己的函数名和文档信息

形参设为不定长参数,也可根据需要自行定义

import functools
def set_fun(func):
    @functools.wraps(func)
    def call_fun(*args,**kwargs):
        # 添加所需的功能
        &"填写需要增加的功能"&
        return func(*args,**kwargs)
    return call_fun

@set_fun
def test(*args,**kwargs):
    pass

1 入门装饰器

单层函数实现装饰器

特点:简介,优美的实现了装饰器的功能,结构简单清晰,装饰器中不运行被装饰函数,不涉及传参问题

         类似于中间件的代码风格

def set_func(func):

    print(func.__name__)
    # 增加需要的功能
    return func


@set_func
def index():
    print("hello,world")

index()

2 进阶装饰器

双层函数装饰器,可传递参数value

def route(value):

    def set_func(func):
        print(value)
        print(func.__name__)
        # 添加需要的功能
        return func

    return set_func

@route("hhhhh") # 实现向装饰器传参
def index():
    print("hello,world")

3 flask route 路由功能路由装饰器源代码

flask 路由装饰器函数,在flask0.1版本中定义于Flask 类下的一个实例方法

实例方法定义为装饰器,同时实现传递复杂参数的操作,值得参考借鉴


class Flask(object):
    ...

    def add_url_rule(self, rule, endpoint, **options):
        “”“装饰器调用函数”“”
        options['endpoint'] = endpoint
        options.setdefault('methods', ('GET',))
        self.url_map.add(Rule(rule, **options))

    def route(self, rule, **options):
        “”“路由功能装饰器”“”
        def decorator(f):
            self.add_url_rule(rule, f.__name__, **options)
            self.view_functions[f.__name__] = f
            return f
        return decorator

4 django 检查用户是否登录装饰器

这里列出的是django2.0 框架中auth 用户模块的一个装饰器,目的检查用户是否登录之类的功能。

三层闭包函数实现传参和装饰功能,结构更容易理解,也很值得借鉴。

def user_passes_test(test_func, login_url=None, redirect_field_name=REDIRECT_FIELD_NAME):
    """
    Decorator for views that checks that the user passes the given test,
    redirecting to the log-in page if necessary. The test should be a callable
    that takes the user object and returns True if the user passes.
    """

    def decorator(view_func):
        @wraps(view_func)
        def _wrapped_view(request, *args, **kwargs):
            if test_func(request.user):
                return view_func(request, *args, **kwargs)
            path = request.build_absolute_uri()
            resolved_login_url = resolve_url(login_url or settings.LOGIN_URL)
            # If the login url is the same scheme and net location then just
            # use the path as the "next" url.
            login_scheme, login_netloc = urlparse(resolved_login_url)[:2]
            current_scheme, current_netloc = urlparse(path)[:2]
            if ((not login_scheme or login_scheme == current_scheme) and
                    (not login_netloc or login_netloc == current_netloc)):
                path = request.get_full_path()
            from django.contrib.auth.views import redirect_to_login
            return redirect_to_login(
                path, resolved_login_url, redirect_field_name)
        return _wrapped_view
    return decorator

end

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值