百万年薪python之路 -- 闭包
2.闭包
闭包的定义:
- 闭包是嵌套在函数中的函数。
- 闭包必须是内层函数对外层函数的变量(非全局变量)的引用。
一句话定义就是:在嵌套函数内,对非全局变量 (且不是本层的变量)的引用
如何判断判断闭包?举例让同学回答:
# 例一:
def wrapper():
a = 1
def inner():
print(a)
return inner
ret = wrapper() #是
print(ret.__code__.co_freevars)
# 例二:
a = 2
def wrapper():
def inner():
print(a)
return inner
ret = wrapper() #不是
print(ret.__code__.co_freevars)
# 例三:
def wrapper(a,b):
def inner():
print(a)
print(b)
return inner
a = 2
b = 3
ret = wrapper(a,b) #是
print(ret.__code__.co_freevars)
以上三个例子,最难判断的是第三个,其实第三个也是闭包,如果我们每次去研究代码判断其是不是闭包,有一些不科学,或者过于麻烦了,那么有一些函数的属性是可以获取到此函数是否拥有自由变量的,如果此函数拥有自由变量,那么就可以侧面证明其是否是闭包函数了(了解):
自由变量的定义:在函数中使用的,但既不是函数参数也不是函数的局部变量的变量
def make_averager():
series = []
def averager(new_value):
series.append(new_value)
total = sum(series)
return total/len(series)
return averager
avg = make_averager()
# 函数名.__code__.co_freevars 查看函数的自由变量
print(avg.__code__.co_freevars) # ('series',)
当然还有一些参数,仅供了解:
# 函数名.__code__.co_freevars 查看函数的自由变量
print(avg.__code__.co_freevars) # ('series',)
# 函数名.__code__.co_varnames 查看函数的局部变量
print(avg.__code__.co_varnames) # ('new_value', 'total')
# 函数名.__closure__ 获取具体的自由变量对象,也就是cell对象。
# (<cell at 0x0000020070CB7618: int object at 0x000000005CA08090>,)
# cell_contents 自由变量具体的值
print(avg.__closure__[0].cell_contents) # []
用闭包写的小爬虫
from urllib.request import urlopen
def get_url():
url = 'http://www.xiaohua100.cn/index.html'
def get():
ret = urlopen(url).read()
print(ret)
return get
get_func = get_url()
get_func()
闭包的作用:保存局部信息不被销毁,保证数据的安全性。
闭包的应用:
- 可以保存一些非全局变量但是不易被销毁、改变的数据。
- 装饰器。
百万年薪python之路 -- 闭包的更多相关文章
- 百万年薪python之路 -- JS基础介绍及数据类型
JS代码的引入 方式1: <script> alert('兽人永不为奴!') </script> 方式2:外部文件引入 src属性值为js文件路径 <script src ...
- 百万年薪python之路 -- 面向对象之继承
面向对象之继承 1.什么是面向对象的继承 继承(英语:inheritance)是面向对象软件技术当中的一个概念. 通俗易懂的理解是:子承父业,合法继承家产 专业的理解是:子类可以完全使用父类的方法和属 ...
- 百万年薪python之路 -- 数据库初始
一. 数据库初始 1. 为什么要有数据库? 先来一个场景: 假设现在你已经是某大型互联网公司的高级程序员,让你写一个火车票购票系统,来hold住十一期间全国的购票需求,你怎么写? 由于在同一时 ...
- 百万年薪python之路 -- 并发编程之 协程
协程 一. 协程的引入 本节的主题是基于单线程来实现并发,即只用一个主线程(很明显可利用的cpu只有一个)情况下实现并发,为此我们需要先回顾下并发的本质:切换+保存状态 cpu正在运行一个任务,会在两 ...
- 百万年薪python之路 -- 前端CSS样式
CSS样式 控制高度和宽度 width宽度 height高度 块级标签能设置高度和宽度,而内联标签不能设置高度和宽度,内联标签的高度宽度由标签内部的内容来决定. 示例: <!DOCTYPE ht ...
- 百万年薪python之路 -- MySQL数据库之 Navicat工具和pymysql模块
一. IDE工具介绍(Navicat) 生产环境还是推荐使用mysql命令行,但为了方便我们测试,可以使用IDE工具,我们使用Navicat工具,这个工具本质上就是一个socket客户端,可视化的连接 ...
- 百万年薪python之路 -- Socket
Socket 1. 为什么学习socket 你自己现在完全可以写一些小程序了,但是前面的学习和练习,我们写的代码都是在自己的电脑上运行的,虽然我们学过了模块引入,文件引入import等等,我可以在程序 ...
- 百万年薪python之路 -- 网络通信原理
1. C/S B/S架构 C: Client 客户端 B: Browse 浏览器 S: Server 服务端 C/S架构: 基于客户端与服务端之间的通信 eg: QQ,微信,LOL,DNF等需要安装A ...
- 百万年薪python之路 -- 面向对象之 反射,双下方法
面向对象之 反射,双下方法 1. 反射 计算机科学领域主要是指程序可以访问.检测和修改它本身状态或行为的一种能力(自省) python面向对象中的反射:通过字符串的形式操作对象相关的属性.python ...
随机推荐
- seo搜索引擎的优化方法
现在互联网的入口,一般都是被搜索引擎霸占.所以我们要想让别人搜索时,优先看到我们的网站.有两种方法: 1.竞价排名.这是需要钱的,给的钱越多,排名越靠前.参考某度.. 2.不想花钱,就使用seo搜索引 ...
- 从零开始入门 K8s | 应用编排与管理(酒祝)
一.需求来源 背景问题 首先来看一下背景问题.如下图所示:如果我们直接管理集群中所有的 Pod,应用 A.B.C 的 Pod,其实是散乱地分布在集群中. 现在有以下的问题: 首先,如何保证集群内可用 ...
- Apache Thrift 的基本使用
Apache Thrift 的基本使用 可以先看看官网是如何介绍的 The Apache Thrift software framework, for scalable cross-language ...
- java 队列和栈相互实现
一.队列实现栈 public class queue2stack { public static void main(String[] args) { QS qs = new QS(); qs.pus ...
- Angular 常用命令行
1. ng -v 查看angular-cli是否安装成功.angular-cli的版本号 2. ng new 项目名称 新建angular项目 3. ng g class 类名 动态生成类文件: 4. ...
- 利用threading模块开线程
一多线程的概念介绍 threading模块介绍 threading模块和multiprocessing模块在使用层面,有很大的相似性. 二.开启多线程的两种方式 1.创建线程的开销比创建进程的开销小, ...
- mysql执行过程以及顺序
前言:mysql在我们的开发中基本每天都要面对的,作为开发中的数据中间件,mysql承担者存储数据和读写数据的职责.因为学习和了解mysql是至关重要的,那么当我们在客户端发起一个sql到出现详细的查 ...
- 3D虚拟环境中的选择技术分类
我们在3D虚拟环境(Virtual Environment, VE)中需要完成的操作有3种:选择物体,操纵(改变)物体,移位(locomotion).这里来总结一下3D VE中的选择技术的种类.本文根 ...
- js中对于数组的操作
let myArray=[11,22,33]; console.log('原数组:',myArray); myArray.push(44,55); console.log('用push在数组后面插入元 ...
- Go中使用seed得到相同随机数的问题
1. 重复的随机数 废话不多说,首先我们来看使用seed的一个很神奇的现象. func main() { for i := 0; i < 5; i++ { rand.Seed(time.Now( ...