python基础语法7 闭包函数与装饰器
闭包函数:
定义:
1 定义再函数内部
2 对外部作用域有引用
闭包函数是 函数嵌套、函数对象、名称空间与作用域 结合体。
- 闭包函数必须有内嵌函数
- 内嵌函数需要引用该嵌套函数上一级变量
- 闭包函数必须返回内嵌函数
# 直接传参
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()
python基础语法7 闭包函数与装饰器的更多相关文章
- python基础-闭包函数和装饰器
闭包函数和装饰器 闭包函数 概念:在函数中(嵌套)定义另一个函数时,内部函数引用了外层函数的名字. 特性 闭包函数必须在函数内部定义 闭包函数可引用外层函数的名字 闭包函数是函数嵌套.函数对象.名称空 ...
- day11 闭包函数和装饰器
1.函数不是新知识点 主要是学习函数的用法 在面向对象编程中,一切皆对象,函数也不例外 具体的表现 1.函数可以引用 2.函数可以作为函数的参数 3.函数可以作为函数的返回值 4.可以被存储到容器类型 ...
- Python基础之函数:2、globlal与nonlocal和闭包函数、装饰器、语法糖
目录 一.global与nonlocal 1.global 2.nonlocal 二.函数名的多种用法 三.闭包函数 1.什么是闭包函数 2.闭包函数需满足的条件 3.闭包函数的作用 4.闭包函数的实 ...
- Python基础(7)闭包函数、装饰器
一.闭包函数 闭包函数:1.函数内部定义函数,成为内部函数, 2.改内部函数包含对外部作用域,而不是对全局作用域名字的引用 那么该内部函数成为闭包函数 #最简单的无参闭包函数 def func1() ...
- python闭包函数与装饰器
目录 闭包函数 闭包概念 实际应用 装饰器 简介 简单版本装饰器 进阶版本装饰器 完整版本装饰器 装饰器模板 装饰器语法糖 装饰器修复技术 问题 答案 闭包函数 闭包概念 闭:定义在函数内部的函数 包 ...
- Python之函数对象、函数嵌套、名称空间与作用域、闭包函数、装饰器
目录 一 函数对象 二 函数的嵌套 三 名称空间和作用域 四 闭合函数 五 装饰器 一.函数对象 1.函数是第一类对象 #第一类对象的特性:# 可以被引用 # 可以当做参数传递 # 返回值是函数 # ...
- python闭包函数及装饰器简介
目录: 闭包函数简介 闭包函数的实际应用 装饰器简介 装饰器初期-完整版 装饰器语法糖 闭包函数简介 1.定义在函数内部的函数(函数的嵌套) 2.内部函数运用外部函数局部名称空间中的变量名 注:函数名 ...
- day11_7.11 闭包函数与装饰器
补充: callable 代表可调用的,加括号可以执行.(函数或者类) import this 查看python之禅 一.闭包函数 所谓闭包函数,就是定义在函数内部的函数,也就是函数定义的嵌套.而在 ...
- CSIC_716_20191112【闭包函数和装饰器】
闭包函数 什么是闭包函数:闭包函数是函数嵌套.函数对象.名称空间和作用域的集合体. 闭包函数必须在函数内部定义,闭包函数可以引用外层函数的名字. # _*_ coding: gbk _*_ # @Au ...
随机推荐
- AQS3---出队(凌乱,供参考,先看AQS2)
出队时候,如果队列处于稳定状态,那么就是一个挨着一个出队,难点在于出队的时候,队列正处于调整阶段,那么此时队列中的关系是混乱无章可寻的. 出队:unlock释放锁,不在队列线程去抢锁,队列第一个正常 ...
- 啊哈!算法(第一章)C#实现
第1节 最简单的排序--桶排序 期末考试完了老师要将同学们的分数按照从高到低排序. 小哼的班上只有 5 个同学,这 5 个同学分别考了 5 分.3 分.5 分.2 分和 8 分,考得真是惨不忍 ...
- 搭建zipkin并以mysql的方式存储数据
zipkin以mysql的方式存储 (centos+java8+mysql+zipkin2.3.1) 前言: 这篇教程用于搭建已mysql作为存储的zipkin.(还不知道zipkin是什么的小伙伴请 ...
- 【题解】分离与合体 [Loj10151]
[题解]分离与合体 [Loj10151] 传送门:分离与合体 \([Loj10151]\) [题目描述] 给定一个长度为 \(n\) 的序列,如果从某个点 \(k\) 处将区间 \([l,r]\) 断 ...
- SQL系列(一)—— SQL简介
在说到SQL之前需要了解一些关于数据库的概念: 数据库(database):是一个以某种有组织的方式存储的数据集合.存储数据的仓库,不过是以一定的组织方式进行存储. DBMS:数据库管理系统.经常遇到 ...
- 关于vs无法创建虚拟目录的问题
插入链接:https://blog.csdn.net/zhao1955/article/details/92182935 补充:改完之后不要忘记以管理员的身份运行vs
- 8、VUE自定义组件
1.为什么要使用自定义组件? 自定义组件是用来封装复杂的内容,提高可重用性,比如封装复杂的表格组件.日历组件.图片轮播组件等. 2.自定义组件 2.1. 全局组件 全局组件是每个Vue对象都能使用的组 ...
- 自定义WPF Popup控件
解决问题 1.WPF Popup 不随着 Window 一起移动的问题 2.WPF Popup 总是显示在最前面 引用命名空间 xmlns:ctrl="clr-namespace:Micro ...
- springboot 全局异常捕获,异常流处理业务逻辑
前言 上一篇文章说到,参数校验,往往需要和全局的异常拦截器来配套使用,使得返回的数据结构永远是保持一致的.参数异常springboot默认的返回结构: { "timestamp": ...
- python基础--py2与py3编码
python2 与 python3的编码和解码 注意:小心,容易弄混 目录: 1.python2d 的encode & decode 2.python3的encode & decode ...