闭包函数
1.闭:定义在函数内部的函数
2.包:内部函数引用了外部函数做用域的名字python
闭包函数:只须要传一次参,下面不管在哪用到,直接拿那个名字就能够了闭包
特色:只给内部传参,须要什么传什么,永远不会变ide
def outter(): #先定义一个outter函数 x = 111 def inner(): print(x) return inner res = outter() # res就是inner函数内存地址 def func(): x = 333 res() func()
给函数体传值的第一种方式 :传参,直接传递数据函数
def index1(username): print(username)
给函数体传参的第二种方式 闭包(包起来,我给你)工具
def outter(x,y): # x = 1 # y = 40 def my_max(): if x > y: return x return y return my_max res1 = outter(1,40) # res就是my_max函数的内存地址 print(res1()) print(res1()) print(res1()) res2 = outter(90,200) print(res2()) print(res2()) print(res2()) print(res2()) print(res2()) print(res2())
须要注意的是url
def outter (x,y) 与 def outter(): x = 1 y = 10 这两种本质是同样的,都是在outter里面绑定两个名字,产生两个值
import requestsspa
第一个直接给函数传参code
url1 = 'https://www.baidu.com' url2 = '...' def my_get(url): response = requests.get(url) if response.status_code == 200: print(len(response.text)) my_get(url1) my_get(url1) my_get(url1) my_get('https://www.baidu.com') my_get('https://www.baidu.com') my_get('https://www.baidu.com')
第二种给函数传参的方式 闭包对象
def outter(url):
# url = 'https://www.jd.com'
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')
my_jd()
my_jd()
my_baidu = outter('https://www.baidu.com')
my_baidu()
my_baidu()
my_baidu()
my_baidu()
my_baidu()
装饰器:
器:就是一个工具
装饰:给被装饰对象添加新的功能blog
为何要用装饰器
开放封闭原则:
开放:对扩展开放
封闭:对修改封闭
装饰器(可调用对象)必须遵循的两个原则:
1.不改变被装饰对象源代码
2.不改变被装饰对象(可调用对象)调用方式
def index():
pass
index()
如何用
"""
import time #统计时间
print(time.time())
#1562812014.731474 时间戳 当前时间距离1970-1-1 00:00:00相差的秒数
#1970-1-1 00:00:00是Unix诞生元年
time.sleep(3) # 让cpu谁三秒 让你的程序暂停三秒
print('FBI warning!')
简单版本装饰器
1.统计index函数执行的时间
import time def index(): time.sleep(3) print('开业了') start = time.time() index() end = time.time() #cpu运行代码的时候速度是很是快的,代码与代码之间距离的时间特别的短, print('index run time:%s'%(end-start))
1.统计index函数执行的时间
import time def index(): time.sleep(3) print('开业了') def outter(func): #func = index函数的内存地址 # func = index def get_time(func): #func=index函数 start = time.time() func() #func=index函数内存地址() 直接调用 运行结束时间 end = time.time() #运行结束时间 print('index run time:%s'%(end-start)) return get_time # res = outter(index) #res变量名 想等于什么就是什么 # res() index = outter(index) #函数名只要加括号,优先级最高 outter(最开始的index函数内存地址) #index指向get_time函数的内存地址 index()
升级版装饰器
import time def index(): time.sleep(3) print('开业了') def login(name): #形参是位置形参 time.sleep(1) print('%s is sb'%name) def outter(func): # func = index def get_time(*args,**kwargs): #func = login函数的内存地址 start = time.time() func(*args,**kwargs) #args = ('egon',) kwargs={} end = time.time() print('index run time:%s'%(end-start)) return get_time # res = outter(index) # res() login = outter(login) #outter(最原始的login函数的内存地址) login是get_time login('egon') index = outter(index) #最原始的index函数 index()
函数参数的问题
无参函数和有参函数均可以直接调用???
函数能够接收任意数量的参数
装饰器的模板
def outter(func): def inner(*args,**kwargs): print('执行被装饰函数以前 你能够作的操做') res = func(*args,**kwargs) print('执行被装饰函数以后 你能够作的操做') return res return inner
装饰器语法糖
@outter #本质是在最前面
@的工做原理:固定语法会将紧挨着它下面的可调用的名字当作它的参数自动传入,直接执行
例如:
index = outter(index)
(自动outter())
mport time def outter(func): # func = 最原始的index函数的内存地址 def get_time(*args, **kwargs): start = time.time() res = func(*args, **kwargs) # 最原始的login函数的内存地址() 直接调用 func('egon') end = time.time() print('func run time:%s'%(end-start)) return res return get_time # login = outter(login) # outter(最原始的login函数的内存地址) # index = outter(index) # home = outter(home) @outter # index = outter(index) outter(最原始的index的函数的内存地址) def index(): time.sleep(3) print('澳门最大线上赌场开业啦 性感tank在线发牌!') return 'index' # res1 = index() @outter # login = outter(login) def login(name): time.sleep(1) print('%s is sb'%name) return 'login' # res = login('egon') @outter # home = outter(home) def home(*args,**kwargs): time.sleep(1) return 'home' # login = outter(login) # outter(最原始的login函数的内存地址) # index = outter(index) # home = outter(home) index() login('egon') home()
注:语法糖在书写的时候应该与被装饰对象牢牢挨着 二者之间不要有空格