装饰器 ==》一个提升逼格的玩意
先来一简单实例,代码如下
def f1(): print('123') def f2(xxx): xxx() f2(f1) # f1没有加括号,代指函数整体,也就是说函数是可以被当作参数传递的!! # 函数只是定义,不被调用,解释器去解释的时候,内部代码是不会执行的!!
python中的装饰器decorator其实是一个高阶函数,它接受一个函数作为参数,并返回一个新的函数,从下往上编译,从上往下执行
def outer(func): def inner(): print("before") func() print("after") return inner @ + 函数名 功能: 1、自动执行outer函数并且将其下面的函数名f1当作参数传递 2、将outer函数的返回值,重复赋值给f1 @outer def f1(): print("F1")
我们可以看到上面代码执行的是一个没有参数的函数,如果函数有参数,并且有多少个参数我们不知道,那该怎么办呢?
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): if USER_INFO.get('age', None) >= 18: # 检查年龄 是否满18 r = f(*args, **kwargs) # 年龄符合,调用方法 return r else: print('你还未成年,一边待着去......') return inner def check_score(f): def inner(*args, **kwargs): if USER_INFO.get('score', None) >= 60: # 检查分数是否合格,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()