作业讲解和昨日回顾
2、动态参数*args ,**kwargs:位置参数,*args,默认参数,**kwargs
命名空间和作用域
作用域链
函数名是第一类对象的概念
二、新内容:闭包
1、闭包的定义:闭包必须是嵌套函数,内部函数引用外部函数的变量
def f1(): b=123 def f2(): print(b)
2、例子:用__closure__检测是不是闭包
def fl(): a=1 def f2(): def f3(): print(a) f3() print("f3:",f3.__closure__) f2() print("f2:",f2.__closure__) fl() # 1 # f3: (<cell at 0x00000000027A85E8: int object at 0x00000000655B60E0>,) # f2: (<cell at 0x00000000027A85E8: int object at 0x00000000655B60E0>,)
3、外面调用里面的函数,是闭包的常用状态
def f1(b): def f2(): print(b) return f2 ff = f1("bbb") ff() #bbb
详细步骤: def f1(): b=10 def f2(): return b ret_b=f2() return ret_b ret_b=f1() print(ret_b) 简写 def f1(): #从内部返回一个值到全局 b=10 def f2(): return b return f2() print(f1())
4、在爬虫中应用闭包
from urllib.request import urlopen def get_url(url): def readl(): ret=urlopen(url).read() print(ret) return readl read_func=get_url("https://i.cnblogs.com/EditPosts.aspx?opt=1") read_func()
三:装饰器
装饰器的作用:在不改变函数的调用方式的情况下,给函数的前后添加新的功能
1、关于时间:计算运行时间差
import time #模块 start_time=time.time() time.sleep(1) end_time=time.time() print("======%s======"%(end_time-start_time))
利用闭包计算时间差
import time def timmer(func): def inner(): start_time=time.time() time.sleep(0.1) func() end_time=time.time() print("===%s==="%(end_time-start_time)) return inner def func(): print("dajiahao") func=timmer(func) func()
# dajiahao
# ===0.1000056266784668===
2、重要模板说明
import time def timmer(qqxing): #timmer是装饰器的名字,传入的参数就是被装饰的函数 def inner(): #在装饰器中需要定义一个内部的函数 print("调用func之前") qqxing() #被装饰的函数,并且要执行 print("调用func之后") return inner #将内部函数的名字返回 def func(): print("dajiahao") func=timmer(func) func()
3、装饰器是闭包的典型应用
语法糖的应用
import time def timmer(qqxing): #timmer是装饰器的名字,传入的参数就是被装饰的函数 def inner(): #在装饰器中需要定义一个内部的函数 print("调用func之前") qqxing() #被装饰的函数,并且要执行 print("调用func之后") return inner #将内部函数的名字返回 @timmer #语法糖 func=timmer(func) def func(): print("dajiahao") func() #调用func之前 #dajiahao #调用func之后
4、完整的装饰器例子
import time def timmer(qqxing): #timmer是装饰器的名字,传入的参数就是被装饰的函数 def inner(name): #在装饰器中需要定义一个内部的函数 print("调用func之前") qqxing(name) #被装饰的函数,并且要执行 print("调用func之后") return inner #将内部函数的名字返回 @timmer #语法糖 func=timmer(func) def func(name): print("%s你好"%(name)) func("虫虫") # 调用func之前 # 虫虫你好 # 调用func之后
5、装饰器的固定结构
# 装饰器的固定结构 def wrapper(func): #timmer 是装饰器的名字,传入的参数就是被装饰的函数 def inner(*args,**kwargs): #在装饰器中需要定义一个内部函数 """被装饰函数之前添加的代码""" ret=func(*args,**kwargs) #被装饰器的函数,并且要执行 # """被装饰函数之后添加的代码""" return ret return inner #将内部函数的名字返回
四、装饰器的开放封闭原则
概念:开放封闭原则
开放: 对扩展是开放的
封闭:对修改是封闭的
装饰器:开放封闭原则
1、例题:利用装饰器设置登录一次的程序
flag=False def login(func): def inner(*args,**kwargs): global flag if flag==False: username=input("用户名:") password=input("密码:") if username=="alex" and password=="someboday": print("登录成功") flag=True if flag==True: ret=func(*args,**kwargs) return ret return inner @login def art(): print("欢迎来到文章页") @login def dar(): print("欢迎来到日志页") art() dar()
记录日志:
def log(func): def inner(*args,**kwargs): print("你要调用%s函数了"%func.__name__) ret=func(*args,**kwargs) return ret return inner @log def f1(): print("f1") @log def f2(): print("f2") f1() f2()