网站备案 子域名,高端广告公司网站建设价格,做瑞士网站,软件开发学什么函数 装饰器 回顾内容#xff1a; 函数可以作为参数进行传递函数可以作为返回值函数名称可以像变量一样进行赋值操作 装饰器#xff1a;要求记住结论 引入#xff1a;
def play_dnf():print(你好啊#xff0c;我是赛利亚#xff0c;今天又是美好的一天)def p…函数 装饰器 回顾内容 函数可以作为参数进行传递函数可以作为返回值函数名称可以像变量一样进行赋值操作 装饰器要求记住结论 引入
def play_dnf():print(你好啊我是赛利亚今天又是美好的一天)def play_lol():print(德玛西亚)print(开挂)
play_dnf()
print(关闭外挂)print(开挂)
play_lol()
print(关闭外挂) 太麻烦聘请管家帮我开启外挂 #函数作为参数进行传递
def guanjia(fn):print(开挂)fn()print(关闭外挂)def play_dnf():print(你好啊我是赛利亚今天又是美好的一天)def play_lol():print(德玛西亚)guanjia(play_dnf) 但成了管家在打游戏了 解决办法 #函数作为参数进行传递
def guanjia(fn):def inner():print(开挂)fn()print(关闭外挂)return innerdef play_dnf():print(你好啊我是赛利亚今天又是美好的一天)def play_lol():print(德玛西亚)play_dnf guanjia(play_dnf)
#让管家把游戏重新封装了我这边把原来的游戏替换掉
play_dnf() #此时运行的是内部函数inner
play_lol guanjia(play_lol)
play_lol() 还是太麻烦 #函数作为参数进行传递
def guanjia(fn):def inner():print(开挂)fn()print(关闭外挂)return innerguanjia #相当于play_dnf guanjia(play_dnf)
def play_dnf():print(你好啊我是赛利亚今天又是美好的一天)guanjia #相当于play_lol guanjia(play_lol)
def play_lol():print(德玛西亚)play_dnf()
play_lol() 本质 装饰器本质上是一个闭包作用是在不改变原有函数的前提下为函数添加新的功能可以在函数的前后添加新的功能但是源代码不改变 运用 在用户登录的地方日志…… 雏形
def wrapper(目标函数):def inner:之前添加事情目标函数执行 fn()之后添加功能return inner #千万别加wrapper # 目标函数 wrapper目标函数 __name__ __name__属性:帮助获取函数的名字 例
def now():print(1111111111111)a now #a是now的别名
b a #b是a的别名
#若别名套用太多不知道别名是哪个函数的
print(b.__name__) #获取别名本身的函数名字结果
now还可以
def guanjia(fn):print(fn.__name__) #看fn是指向哪个函数 练习 记录玩游戏的时间装饰器 import time #引入时间模块后面会讲 time.time() #时间戳指格林威治时间1970年01月01日00时00分00秒北京时间 1970年01月01日08时00分00秒起至现在的总秒数 time.sleep(x) #沉睡x秒 例
import timedef time_01(fn):def inner():start_time time.time()fn()end_time time.time()execution_time end_time - start_timeprint(f{fn.__name__}函数的执行时间是{execution_time})return innertime_01
def test1():time.sleep(3)print(1111)test1()结果
1111
test1函数的执行时间是3.002014398574829 被装饰函数的参数问题 因为装饰器是将 目标函数 wrapper目标函数 即 目标函数 wrapper(目标函数)wrapper.inner 所以我们要传参的话inner(x,x)需要有形参接收 例
def inner(name,pwd): 但装饰器如果装饰不同函数的话不同函数的形参需求不同的话还是会报错 例
guanjia
def play_wz(uname,pwd):guanjia
def play_lol(uname,pwd,area):所以我们可以用可变参数来解决*args, **kwargs def guanjia(fn):def inner(*args, **kwargs):#* ,** 表示借助所有传进来的实参,打包成元组和字典print(开挂)fn(*args, **kwargs)#*,**表示把元组和字典打散成位置参数以及关键字参数传递进去print(停止游戏关闭外挂)return innerguanjia # 相当于play_wzgunajia(play_wz)
def play_wz(uname, password):print(f用户名是{uname},密码是{password})print(来和妲己玩耍吧)guanjia
def play_cj(uname, password, hero):print(f用户名是{uname},密码是{password},英雄是{hero})print(注意标记点)play_wz(gouxin, 123456)
play_cj(gouxin, 123456, daji)
play_cj(uname lisi,password 123456,hero nanjing)结果
开挂
用户名是gouxin,密码是123456
来和妲己玩耍吧
停止游戏关闭外挂
开挂
用户名是gouxin,密码是123456,英雄是daji
注意标记点
停止游戏关闭外挂
开挂
用户名是lisi,密码是123456,英雄是nanjing
注意标记点
停止游戏关闭外挂 添加**kwargs的原因是 如果有人传参时是用关键字形式传参只写*args就会报错如下 def inner(*args):play_cj(uname lisi,password 123456,hero nanjing) 装饰器的返回值 如果游戏函数结束后要返回一个值这怎么解决呢 直接上代码注释讲解 def guanjia(fn):def inner(*args,**kwargs):print(开挂)ret fn(*args,**kwargs) #用ret接收返回的值print(关闭外挂)return ret #再将ret返回出去作为inner即play_wz的返回值return innerguanjia # play_wz guanjia(play_wz)
def play_wz(uname,pwd):print(来和妲己玩耍啊~)print(f用户名是{uname},密码是{pwd})return 妲己66666 #运行完返回一个值guanjia
def play_lol(uname,pwd,area):print(德玛西亚)print(f用户名是{uname},密码是{pwd},地区是{area})a play_wz(zs,123456) #用a来接收返回值
print(a) #打印返回值即游戏的返回值
play_lol(uname lisi,pwd 123456,area nanjing)结果
开挂
来和妲己玩耍啊~
用户名是zs,密码是123456
关闭外挂
妲己66666 #结束后返回的值
开挂
德玛西亚
用户名是lisi,密码是123456,地区是nanjing
关闭外挂一个函数可以被多个装饰器装饰 如果一个函数可以被多个装饰器装饰是如何运行的呢 def wrapper1(fn):def inner(*args,**kwargs):print(第一个装饰器)fn()print(第一个装饰器结束)return innerdef wrapper2(fn):def inner(*args,**kwargs):print(第二个装饰器)fn()print(第二个装饰器结束)return innerwrapper1 #test wrapper1(test)wrapper1(wrapper2.inner)wrapper1.inner
wrapper2 #test wrapper2(test)wrapper2.inner
def test():print(我是函数)test()结果
第一个装饰器
第二个装饰器
我是函数
第二个装饰器结束
第一个装饰器结束先装饰函数的上面的一层即wrapper2再依次往上装饰即wrapper1 最后运行test( )即运行wrapper1.inner 所以可以看结果来理解运行顺序