python中的装饰器

          其实去年就开始学python了,零零散散,陆陆续续学了点,期间学习了python web开发,爬虫系统;但是一些基础性的知识点长时间不看了就会忘,所以写个博客记录下来,忘了可以随时查看,不用回去看代码了,希望也能帮助大家学习哈。

        python中的装饰器decorator其实是一个高阶函数,它接受一个函数作为参数,并返回一个新的函数,它的执行是由外向内的,代码如下

#装饰器函数
def log(f):
    def fn():
        print (('call ') + f.__name__ + '()...')
        r =  f()   # 这个函数就是调用的 f1()函数
        return r   #返回f1() 函数的执行结果
    return fn

@log    #1.自动执行log函数,并且将其下面的函数名f作为参数
def f1():
    print('我是函数F1')


f1()
#输出结果
#   call f1()...
#   我是函数F1

我们可以看到上面代码执行的是一个没有参数的函数,如果函数有参数,并且有多少个参数我们不知道,那该怎么办呢?非常好的一点是python里面提供了万能参数供我们使用,如果对 万能参数不明白的可以看我的 上一篇博客

def log2(f):
    def inner(*args,**kwargs):  #这2个参数 会接受任意类型的参数
        print('before')
        r = f(*args,**kwargs)
        print('after')
        return r
    return inner

@log2
def f2(name,age):
    print('My name is %s ,I am %s years old'%(name,age))

f2('Eric',24)
#输出
# before
# My name is Eric ,I am 24 years old
# after

比方说一所中学有一个夏令营的活动,夏令营有各种活动,但是每个活动对学生的要求不一样,有的活动要求学生必须满18岁,有的活动要求学生必须考试分数及格(60),还有的活动必须要求学生2个都满足,每个活动都可以写成一个函数,如果这些要求条件我们都写成装饰器的话,就有点太冗余了,还好就是可以多重装饰,简单说就是一个函数可以有多个装饰器,代码如下

USER_INFO = {'age':0,'score':0}  # 用户分数  #用户年龄

def check_age(f):
    def inner(*args,**kwargs):
       #检查年龄 是否满18
       if USER_INFO.get('age',None) >= 18:
           r = f(*args,**kwargs)   #年龄符合 调用方法
           return r
       else:
           print('你还未成年,一边待着去......')
    return inner

def check_score(f):
    def inner(*args, **kwargs):
        #检查分数是否合格  60份合格
        if USER_INFO.get('score',None) >= 60:
            r = f(*args, **kwargs)
            return r
        else:
            print('你考试不合格,继续努力......')
    return inner

# 2个装饰器修饰 会先执行判断年龄的装饰器,在执行判断分数的装饰器
@check_age
@check_score
def swimming():
    print('欢迎来游泳'.center(40, '*'))

@check_age
def basketball():
    print('欢迎来篮球队玩耍'.center(40,'*'))

@check_score
def football():
    print('欢迎来足球队飞'.center(40, '*'))
'''
  1.篮球不需要分数,但是要年龄满18岁
  2.足球不需要年龄,但要分数满60
  3.游泳急需要年龄满18 有需要分数满60
'''
def main():
    while True:
        imp = input('1.篮球,2.足球,3.游泳\n>>>')
        age = input('请输入你的年龄:')
        score = input('请输入你的分数:')
        USER_INFO['age'] = int(age)
        USER_INFO['score'] = int(score)
        if imp == '1':
            basketball()
        elif imp == '2':
            football()
        elif imp == '3':
            swimming()

if __name__ == '__main__':
    main()






以下是一些常见的 Python 装饰器面试问题及其回答: 1. 什么是装饰器装饰器Python 中一种高级的语法结构,它允许在不修改原函数代码的情况下,对函数进行增强或修改。装饰器本质上是一个函数,它接收一个函数作为参数,并返回一个函数。 2. 装饰器有哪些应用场景? 装饰器可以用于实现各种功能,如: - 日志记录:记录函数的调用时间、输入参数、输出结果等信息。 - 计时器:统计函数的运行时间。 - 缓存:缓存函数的输出结果,避免重复计算。 - 权限验证:验证用户是否有权调用函数。 - 接口限流:限制函数的调用频率。 3. 装饰器的语法是什么? 装饰器的语法如下: ```python @decorator def func(): pass ``` 其中,`decorator` 是装饰器函数,`func` 是被装饰函数。装饰器函数可以在函数执行前后对函数进行修改或增强。如果需要传递参数,可以使用带参数的装饰器,如: ```python @decorator(arg1, arg2, ...) def func(): pass ``` 4. 装饰器的执行顺序是怎样的? 多个装饰器会按照从下往上的顺序依次执行,即先执行最外层的装饰器,然后执行内层的装饰器,最后执行被装饰的函数。例如: ```python @a @b @c def func(): pass ``` 执行顺序为 `func = a(b(c(func)))`。 5. 装饰器中如何传递参数? 装饰器可以使用带参数的形式,例如: ```python def my_decorator(arg1, arg2): def decorator(func): def wrapper(*args, **kwargs): # 在这里对函数进行增强或修改 return func(*args, **kwargs) return wrapper return decorator @my_decorator(arg1, arg2) def my_func(): pass ``` 在这个例子中,`my_decorator` 是一个带参数的装饰器,它接收两个参数 `arg1` 和 `arg2`。`decorator` 是一个不带参数的装饰器函数,它接收一个函数作为参数,并返回一个函数。`wrapper` 是被返回的函数,它接收任意数量的位置参数和关键字参数,并在其中对函数进行增强或修改。最后,使用 `@my_decorator(arg1, arg2)` 语法将装饰器应用到函数上。 6. 装饰器中如何保留被装饰函数的元信息? 当使用装饰器时,有时候需要保留被装饰函数的元信息,例如函数名、文档字符串等。为了实现这个功能,可以使用 `functools.wraps` 装饰器,它可以将被装饰函数的元信息复制到装饰器函数中。例如: ```python import functools def my_decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): # 在这里对函数进行增强或修改 return func(*args, **kwargs) return wrapper @my_decorator def my_func(): """这是一个示例函数""" pass ``` 在这个例子中,使用 `@functools.wraps(func)` 语法将被装饰函数的元信息复制到 `wrapper` 函数中。这样,当调用 `help(my_func)` 时,可以看到函数的文档字符串和函数名。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值