闭包函数:

定义:

  1 定义再函数内部

  2 对外部作用域有引用

闭包函数是 函数嵌套、函数对象、名称空间与作用域 结合体。

创建闭包必须满足以下3点: 
  1. 闭包函数必须有内嵌函数
  2. 内嵌函数需要引用该嵌套函数上一级变量
  3. 闭包函数必须返回内嵌函数
# 直接传参
def func(x):
print(x) func(1000) # 通过闭包函数传参
def outer(number):
# number = 100
# inner就是闭包函数
def inner():
print(number)
return inner func = outer(1000) # ---》 inner地址 ---》 func变量名
func() # func ---> inner地址()

闭包函数的应用

# 方式一: 直接传参
def spider_func(url):
# 往url地址发送请求,获取响应数据
response = requests.get(url) # 必须接受url
# 状态码: 200
if response.status_code == 200:
# 获取当前url地址中所有的文本
print(len(response.text))
print(response.text)
url = 'https://www.cnblogs.com/xiaoyuanqujing/'
spider_func(url)
——————————————————————————
# 方式二: 通过闭包函数接受url地址,执行爬取函数
def spider_outer(url):
# url = 'https://www.cnblogs.com/xiaoyuanqujing/'
def spider_inner():
response = requests.get(url)
if response.status_code == 200:
print(len(response.text))
return spider_inner # 爬取 小猿取经
spider_blog = spider_outer('https://www.cnblogs.com/xiaoyuanqujing/')
spider_blog()
# 爬取 京东
spider_baidu = spider_outer('https://www.baidu.com/')
spider_baidu()

装饰器:

  不修改被装饰对象的源代码  
  不修改被装饰对象的调用方式

  被装饰对象: ---> 需要添加功能 函数
  装饰器: ---> 被装饰对象添加的新功能的 函数

  time_record ---》 装饰器

需求: 统计下载电影函数的运行时间。

# 下载电影功能(初始代码)
def download_movie():
print('开始下载电影...')
# 模拟电影下载时间 3秒
time.sleep(3) # 等待3秒
print('电影下载成功...')
return 'sean与jason的雨后的小故事.mp4' start_time = time.time() # 获取当前时间戳
download_movie()
end_time = time.time() # 获取当前时间戳
print(f'消耗时间: {end_time - start_time}')
# 问题: 多个被装饰对象,需要写多次统计时间的代码,导致代码冗余。
# 装饰器: 初级版
def time_record(func):
def inner(*args, **kwargs):
# 统计开始
start_time = time.time() # 被装饰对象, 问题1: 有返回值, 问题2: 不确定参数的 个数
res = func(*args, **kwargs) # func() ---> download_movie()
# 当被统计的函数执行完毕后,获取当前时间
end_time = time.time()
# 统计结束,打印统计时间
print(f'消耗时间: {end_time - start_time}') return res return inner download_movie = time_record(download_movie) # inner
# name = 'egon'
# download_movie(name)
download_movie(name='egon') # inner() # inner() ---> download_movie() # download_movie = time_record(download_movie) # inner

# download_movie()  #  download_movie() ---> download_movie()
# 问题1: 被装饰对象 有返回值

# 下载电影功能
def download_movie():
print('开始下载电影...')
# 模拟电影下载时间 3秒
time.sleep(3) # 等待3秒
print('电影下载成功...')
return '小泽.mp4' def time_record(func): # func <-- download_movie # 在闭包函数中
def inner():
# 统计开始
start_time = time.time()
res = func() # func() ---> download_movie()
# 当被统计的函数执行完毕后,获取当前时间
end_time = time.time()
# 统计结束,打印统计时间
print(f'消耗时间: {end_time - start_time}') return res return inner download_movie = time_record(download_movie)
download_movie()
#问题2: 被装饰对象 有参数
#下载电影功能
import time
def download_movie(url):
print(f'{url}中的电影开始下载了...')
# 模拟电影下载时间 3秒
time.sleep(3) # 等待3秒
print('电影下载成功...')
return '小泽.mp4' def time_record(func): # func <-- download_movie
# url = 'https://www.baidu.com/' # 在闭包函数中
def inner(url):
# 统计开始
start_time = time.time() res = func(url) # func(url) ---> download_movie(url) # 当被统计的函数执行完毕后,获取当前时间
end_time = time.time()
# 统计结束,打印统计时间
print(f'消耗时间: {end_time - start_time}')
return res
return inner download_movie = time_record(download_movie) download_movie(url) --> inner(url)
download_movie('https://www.baidu.com')
#问题4: 假如被装饰对象需要接收多个参数
def download_movie(url, url2, url3):
print(f'{url}中的电影开始下载了...')
# 模拟电影下载时间 3秒
time.sleep(3) # 等待3秒
print('电影下载成功...')
return '小泽.mp4' def download_movie():
print('电影开始下载...')
# 模拟电影下载时间 3秒
time.sleep(3) # 等待3秒
print('电影下载成功...')
return '小泽.mp4'
# 装饰器最终版本
def time_record(func): # func <-- download_movie
# 在闭包函数中
def inner(*args, **kwargs): # *args, **kwargs接收所有参数 # 统计开始
start_time = time.time() # 将被装饰对象需要接收的任意参数 原封不动传给func --》 被装饰对象
res = func(*args, **kwargs) # func(url) ---> download_movie(url) # 当被统计的函数执行完毕后,获取当前时间
end_time = time.time()
# 统计结束,打印统计时间
print(f'消耗时间: {end_time - start_time}') return res
return inner # download_movie = time_record(download_movie)
#
# download_movie()
# download_movie(url) --> inner(url, url2, url3)
# download_movie(url1='https://www.baidu.com', url2='url2', url3='url3')
# 装饰器模板:权限设定
# 装饰器最终版本
def wrapper(func): def inner(*args, **kwargs): # 让用户输入内容
username = input('请输入名字') if username == 'tank':
# 调用被装饰对象,得到返回值
res = func(*args, **kwargs)
return res else:
print('用户权限不足!') return inner def func1():
pass func1 = wrapper(func1)
func1() # inner()

装饰器的语法糖,是属于装饰器的。
@: 装饰器的语法糖

# 注意: 在使用装饰器语法糖时,装饰器必须定义在被装饰对象之上。

import time

# 统计函数执行时间装饰器
def wrapper(func): # 被装饰对象
def inner(*args, **kwargs): # 被装饰对象的参数
# 调用前增加新功能
start_time = time.time()
# 调用被装饰对象,并接收返回值
res = func(*args, **kwargs) # 调用后添加新功能
end_time = time.time()
print(end_time - start_time) return res
return inner # func函数需要执行3秒 # 无参装饰器
# 使用装饰器
@wrapper # wrapper(func) ---> func
def func(): time.sleep(3) func()

最新文章

  1. ASP.NET MVC5 网站开发实践(二) Member区域 - 用户部分(3)修改资料、修改密码
  2. ionic tabs置顶
  3. Android Builder模式在开发中的应用
  4. ibatis CDATA
  5. PLSQL_基础系列06_判断操作NVL / NULLIF / COALESCE / NVL2(案例)
  6. 构建工具Gradle安装和简单使用
  7. [异常解决] Make nRF51 DFU Project Appear &quot;fatal error: uECC.h: No such file or directory&quot;
  8. hadoop端口配置指南
  9. 深入浅出Ajax(一)
  10. [c#]解决方案:需要“jquery”ScriptResourceMapping。请添加一个名为 jquery (区分大小写)的 ScriptResourceMapping。
  11. 将字符串当做是php代码执行的函数eavl()
  12. Android OpenGL ES(八)----纹理编程框架
  13. Helm 入门指南
  14. http 连接 analysis service (ssas)
  15. 吴裕雄 05-mysql删除数据库
  16. git diff 分支1 分支2 --stat命令没有将所有的不同显示出来
  17. 北美IT求职攻略
  18. 关于如何使用Microsoft Word发博客
  19. vCenter 6.5安装
  20. H-a

热门文章

  1. Maven 教程(12)— Maven生命周期和插件
  2. 在电脑上部署网站lls 浏览器上访问
  3. 045 用户登录功能01----JWT和后台代码
  4. keil 编译器V6 定义函数在ram中运行-和在指定地址定义常量
  5. 阿里云CentOS服务器下安装Golang1.13并配置代理
  6. Oracle批量、大量Update方法总结
  7. 【java】java 读写文件
  8. javascript query string
  9. spring mvc 服务器端输出一条可执行js
  10. 手写Ajax的意义所在,从青铜到钻石!