一、闭包函数
闭:定义在函数内部的的函数
包:内部函数引用了外部函数作用域的名字
def outter(): x = 111 def inner(): print(x) return inner res = outter()
在这样的情况下x,如果在全局空间中,对x再怎么赋值。x永远是111,即为封闭,而x是在内部函数中,获取了外层函数的赋的值,即为包。
函数传参的两种方法:
第一种:直接给函数传参
import requests url1 = 'https://www.baidu.com' def my_get(url): response = requests.get(url) if response.status_code == 200: print(len(response.text)) my_get(url1)
第二种:闭包方式
def outter(url): def my_get(): response = requests.get(url) if response.status_code == 200: print(len(response.text)) return my_get() my_jd = outter('https://www.jd.com')
二、装饰器
器:就是一个工具
装饰:给被装饰对象添加新的功能
为什么要用装饰器:
开放封闭原则:
开放:对扩展开放
封闭:对修改封闭
装饰器(可调用对象)必须遵循的两个原则:
1.不改变装饰对象源代码
2.不改变装饰对象(可调用对象)调用方式
def index(): pass index()
1.统计index函数执行的时间
我们从简单的装饰器开始慢慢进阶
1 #装饰器1.0 2 import time 3 def index(): 4 time.sleep(3) 5 print('今天的鸡哥又是格外的帅气!') 6 def outter(func): 7 def get_time(): 8 start = time.time() 9 func() 10 end = time.time() 11 print('index run time:%s'%(end - start)) 12 return get_time 13 index = outter(index) 14 index()
简单标个步骤流程:
但是简单装饰器有个弊端,就是它的内部函数是无参的,但凡你外部调用函的数中含有参数,内部函数就会报错,然后我们在原基础上,稍作修改得到一个装饰器的进阶版本。
#装饰器2.0
1 import time 2 def index(): 3 time.sleep(3) 4 print('今天的鸡哥又是格外的帅气!') 5 def joke(name): 6 time.sleep(1) 7 print('今天的%s只能做衬托...'%name) 8 def outter(func): 9 def get_time(*args,**kwargs): #进行打包 10 start = time.time() 11 func(*args,**kwargs)#进行打散 12 end = time.time() 13 print('index run time:%s'%(end - start)) 14 return get_time 15 index = outter(index) 16 index() 17 joke = outter(joke) 18 joke('tank')
虽然上面我们已经弥补了装饰器1.0的缺陷,但是有个问题,index = outter(index) 看起来是不是有那么一些绕,虽然我们这边用到了“以假乱真”这种办法,但是有没有比这种方法表达更好看的办法呢,那么就有了装饰器语法糖
# 装饰器最终版本
1 import time 2 def outter(func): 3 def get_time(*args,**kwargs): #进行打包 4 start = time.time() 5 func(*args,**kwargs)#进行打散 6 end = time.time() 7 print('index run time:%s'%(end - start)) 8 return get_time 9 @outter # index = outter(index) 10 def index(): 11 time.sleep(3) 12 print('今天的鸡哥又是格外的帅气!') 13 @outter #joke = outter(joke) 14 def joke(name): 15 time.sleep(1) 16 print('今天的%s只能做衬托...'%name) 17 18 index() 19 joke('tank')
使用方法:@+函数名
认证装饰器:
要求:执行函数index之前必须先输入用户名和密码 正确之后才能执行index
否则提示用户输入错误 结束程序
1 def login(func): 2 def inner(*args,**kwargs): 3 username = input('please input your name>>>') 4 password = input('please input your password>>>') 5 if username == 'zzj' and password == '123456': 6 func(*args,**kwargs) 7 else: 8 print('username or password error!') 9 return inner 10 11 @login 12 def index(name): 13 print('%s is a good gay'%name) 14 return 666 15 16 index('jason')