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 ...
随机推荐
- 【linux】查看jar里面的配置文件
1.vim 文件.jar 2.光标到配置文件,然后回车 3.退出命令:q 也可以进行编辑,按i进入编辑,按:wq保存退出
- thinkPHP5如何使用rabbitmq
thinkPHP5如何使用rabbitmq? 安装好 tp5 的 rabbitmq 扩展后,在项目根目录文件添加文件 rabbitmq.php 引导启动 rabbitmq. <?php defi ...
- ElasticSearch中碰到的C10K问题
Elasticsearch基于Netty解决C10K问题背后的原理是JAVA NIO中的IO多路复用机制,涉及到三大"组件":SelectableChannel.Selector. ...
- Kafka学习笔记之如何永久删除Kafka的Topic
0x00 问题描述 使用kafka-topics --delete命令删除topic时并没有真正的删除,而是把topic标记为:“marked for deletion”,导致重新创建相同名称的Top ...
- TServerSocket组件
主要作为服务器端的套接字管理器使用.它封装了服务器端的套接字.在打开套接字后,服务器端就处于监听状态,在接收到其它机器的连接请求后,与客户端建立连接,创建一个新的套接字,用于和客户端互传数据,此时TS ...
- JavaScript入门(二)
JavaScript入门—操作DOM树 要点 DOM树是一个树形结构,操作DOM树通常是“更新.遍历.新增.删除”. 更新DOM树 拿到DOM节点 var id=document.getElement ...
- Netty高性能原理和框架架构解析
1.引言 Netty 是一个广受欢迎的异步事件驱动的Java开源网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端. 本文基于 Netty 4.1 展开介绍相关理论模型,使用场景,基本组件 ...
- docker系列之一:初见docker
什么是docker? docker是目前linux最流行的容器技术,Docker 将应用程序与该程序的依赖,打包在一个文件里面.运行这个文件,就会生成一个虚拟容器.程序在这个虚拟容器里运行,就好像在真 ...
- PyTorch 安装 报错,原因是pip 不是64位的。
原因: import pip._internal print(pip._internal.pep425tags.get_supported()) 换位64位的python版本. import pip. ...
- mysql 使用 MD5函数 校验账号密码
项目中账号密码需要加密操作,数据库用户表账号是明文,密码是密文,但是前端传递过来的都是密文,所以需要到数据库中加密账号和前端传递过来的密文做校验. 这时候就可以使用md5函数. 使用案例: SELEC ...