闭:指定义在函数内的函数
包:指该函数包含对外部作用域名字的引用
def f1():
x=1
def inner():
print(x)
return inner
func=f1()
def f2():
x=1111111111 #和调用位置无关要到定义阶段去找
func()
f2()
输出1
def f1():
x=1
def inner():
print(x)
return inner
f=f1()
f1() # 这是一个闭包函数
# 为函数体传值方式 1 使用参数形式
def f1(x):
print(x)
f1(1)
# 为函数体传值方式2 包给函数
def outter(x):
def inner():
print(x)
return inner
f=outter(5)
f()
爬虫小例子
import requests # 导入模块
def outter(url):
def get():
response=requests.get(url)
if response.status_code==200:
print(response.text)
return get
baidu=outter('https://www.baidu.com')
python=outter('https://www.python.org')
baidu()
baidu()
装饰器
什么是装饰器
器: 是指程序中的函数具备某种功能
装饰: 为被装饰对象添加的额外功能
装饰器可以是任意可调用的对象 被装饰的对象也可以是任意课调用的对象
为什么用装饰器
软件一旦上线 对修改源代码是封闭的 对扩展功能是开放的 这就用到装饰器
1 不修改被装饰对象的的源代码
不修改被装饰对象的调用方式
3 如何用装饰器
import time # 导入模块
def index():
print('welcom to index')
time.sleep(3) # 推行执行时间的 秒数
index()
执行后没有统计多长时间 所以加个功能 统计运行时间的功能
import time #导入模块
def index():
start=time.time()
print('welcom to index')
time.sleep(3) # 推行执行时间的 秒数
stop=time.time()
print('run time is %s'%(stop-start))
index() # 这样写改写了源代码 不可以
用装饰器写
import time
def index():
print('welcom to index')
time.sleep(3)
def timmer():
start = time.time()
index()
stop=time.time()
print('run time is %s'%(stop-start))
timmer()
但是装饰器被写死了 只能给index统计时间 以后还要用到其他的函数的统计时间
import time
def index():
print('welcom to index')
time.sleep(3)
def timmer(func): # 传入func
start = time.time()
func() # 把index变成 func()
stop=time.time()
print('run time is %s'%(stop-start))
timmer(index) # 也不好 因为改变了调用方式
**************************************************************
import time
def index():
print('welcom to index')
time.sleep(3)
def timmer(func): #4然后外面来一个函数 把下面的缩进
#func=index #2上面写一个参数 = index
def wrapper(): # wrapper 是装饰的意思 #1 定义一个函数 (内部的代码块是新功能)
start=time.time() # 统计时间开始
func()
stop=time.time() # 统计时间结束 #5在调整注释掉 2 , 把这个数放到4 的括号内
print('run time is %s'%(stop-start))
return wrapper #3 下面一个return 返回 wrapper
index=timmer(index) # index是wrapper函数的地址 #6 index = timmer(index), index()
index()
装饰器的固定写法 :
4然后外面来一个函数 把下面的缩进
2上面写一个参数 = index
1 定义一个函数 (内部的代码块是新功能)
3 下面一个return 返回 wrapper
5在调整注释掉 2 , 把这个数放到4 的括号内
6 index = timmer(index)
index()
练习
import requests
respones=requests.get('https://image.baidu.com')
respones.status_code==200
print(respones.text)
当参数传值
def func():
print('from aaa')
def foo(v):
print(v)
v()
foo(func)
输出
<function func at 0x000001FBFDAFA6A8>
from aaa
引用
def func():
print('from aaa')
f=func
print(f)
f()
输出
<function func at 0x0000021CC6F8A6A8>
from aaa
返回值
def func():
print('ssssssss')
def foo(x):
return x
res=foo(func)
print(res)
res()
输出
<function func at 0x0000014910FFA6A8>
Ssssssss
装饰器语法糖
在被装饰对象上方并且单独一行写着@ 装饰器名字
import time
def timmer(func):
def wrapper(*args,**kwargs):
start=time.time()
res=func(*args,**kwargs)
stop=time.time()
print('run time is %s' %(stop-start))
return res
return wrapper
@timmer #将正下方的函数名字做参数传给timmer然后将值赋给原函数名index
def index():
print('welcome to index')
time.sleep(3)
return 123
@timmer ##将正下方的函数名字做参数传给timmer然后将值赋给原函数名home
def home(name):
print('welcome%sto home page'% home)
time.sleep(2)
res=index()
home('egon')
#
总结 : 装饰器写法
def deco(func):
def wrapper(*args,**kwargs):
res=func(*args,**kwargs)
return res
return wrapper