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 ...
随机推荐
- selenium爬虫入门(selenium+Java+chrome)
selenium是一个开源的测试化框架,可以直接在浏览器中运行,就像用户直接操作浏览器一样,十分方便.它支持主流的浏览器:chrome,Firefox,IE等,同时它可以使用Java,python,J ...
- Range Sum Query - Mutable 精简无递归线段树
操作: 单点更新,区间求和 区间求和:如sum [3,10) 需要对19,5,12,26节点求和即可. 观察可知,左端点为右子节点(奇数)时直接相加,右端点为左子节点(偶数)时直接相加,两边向中间移动 ...
- Qt3D NodeInstantiator 使用时报出index out of range错误的记录
最近用到NodeInstantiator批量加入实体 刚开始用的时候一直程序崩溃 错误代码大致如下: // main.qml ApplicationWindow { ...... Loader { i ...
- 【题解】Luogu P5301 [GXOI/GZOI2019]宝牌一大堆
原题传送门 首先先要学会麻将,然后会发现就是一个暴力dp,分三种情况考虑: 1.非七对子国士无双,设\(dp_{i,j,k,a,b}\)表示看到了第\(i\)种牌,一共有\(j\)个\(i-1\)开头 ...
- winform实现Session功能(保存用户信息)
问题描述:在winform中想实现像BS中类似Session的功能,放上需要的信息,在程序中都可以访问到. 解决方案:由于自己很长时间没有做过winform的程序,一时间竟然手足无措起来.后来发现wi ...
- systemd - CentOS 7进程守护&监控
需求: 运行环境为CentOS 7系统,我们开发了一个程序,需要在开机时启动它,当程序进程crash或者开机之后,守护进程立即拉起进程. 解决方案: 使用CentOS 7中的init进程systemd ...
- C#中字符串转换为计算公式
添加COM引用: private void button_Click(object sender, EventArgs e) { MSScriptControl.ScriptControl sc = ...
- 2019 花椒直播java面试笔试题 (含面试题解析)
本人5年开发经验.18年年底开始跑路找工作,在互联网寒冬下成功拿到阿里巴巴.今日头条.花椒直播等公司offer,岗位是Java后端开发,因为发展原因最终选择去了花椒直播,入职一年时间了,也成为了面 ...
- Python pip安装第三方库的国内镜像
Windows系统下,一般情况下使用pip在DOS界面安装python第三方库时,经常会遇到超时的问题,导致第三方库无法顺利安装,此时就需要国内镜像源的帮助了. 使用方法如下: 例如:pip inst ...
- 安装fastnlp
直接 pip install fastnlp 如果出现 torch的安装报错,可能与操作系统及 CUDA 的版本相关.直接上pytorch 的官网 https://pytorch.org/get-st ...