Python函数装饰器

一、什么是函数装饰器?

函数装饰器用于在源码中标记函数,以某种方式增强函数的行为。

装饰器是可调用对象,其参数是另外一个函数(被装饰的函数)。装饰器可能会处理被装饰的函数,然后把它返回,或者将其替换成另一个函数或可调用对象。

听起来有点模糊,具体是什么意思呢?首先我们来理解一下Python中的函数。

def hi(name="jack"):
    return "hi " + name

print(hi())         # output: 'hi jack'
# 我们甚至可以将一个函数赋值给一个变量,比如
greet = hi
# 我们这里没有在使用小括号,因为我们并不是在调用hi函数
# 而是在将它放在greet变量里头。我们尝试运行下这个
print(greet())      # output: 'hi jack'

del hi              # 如果我们删掉旧的hi函数,看看会发生什么!
print(hi())  # outputs: NameError
print(greet())  # outputs: 'hi jack'

上面是python函数的基础知识,下面来看看装饰器在函数中的使用

#定义一个装饰器
def deco(func):
    def inner():
        print('hello boys')
    return inner

@deco               #装饰函数
def target1():
    print('hi girls')

def target2():
    print('hi boys and girls')

target1()           #调用target1函数
x = deco(target2)  # target2没加(),只作为deco装饰器的参数
x()                 #结果跟使用装饰器一样

可以看到target1函数使用装饰器和以target2函数作为装饰器的参数的结果是一样的。
在这里插入图片描述

二、 装饰器的应用场景

授权(Authorization)
装饰器能有助于检查某个人是否被授权去使用一个web应用的端点(endpoint)。它们被大量使用于Flask和Django web框架中。以下是两个应用:

发送邮件确认身份

from functools import wraps
#不带参数的装饰器
def confirm_required(func):
    @wraps(func)
    def decorated_function(*args, **kwargs):
        if not current_user.confirmed:
            message = Markup(
                'Please confirm your account first.'
                'Not receive the email?'
                '<a class="alert-link" href="%s">Resend Confirm Email</a>' %
                url_for('auth.resend_confirm_email'))
            flash(message, 'warning')
            return redirect(url_for('main.index'))
        return func(*args, **kwargs)
    return decorated_function

使用functools模块提供的wraps装饰器可以避免被装饰函数的特殊属性被修改,比如函数名称__name__被更改,如果不使用该模块,则会导致函数名称被替换,从而导致端点值(端点的默认值即函数名)出错。

权限验证

from functools import wraps
#带参数的装饰器
def permission_required(permission_name):
    def decorator(func):
        @wraps(func)
        def decorated_function(*args, **kwargs):
            if not current_user.can(permission_name):
                abort(403)
            return func(*args, **kwargs)
        return decorated_function
    return decorator

在这里插入图片描述
严格来说,装饰器只是语法糖。装饰器可以像常规的可调用对象那样调用,其参数是另一个函数。

装饰器的特点:

  1. 能把被装饰函数替换成其它函数
  2. 装饰器在加载模块时立即执行。例如在hello2.py文件中导入前面有deco装饰器的hello1.py文件,当import hello1时,deco装饰器立即执行,即会输出hello boys。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值