百万年薪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 ...
随机推荐
- (转)阿里云CentOS 7下配置及使用mysql
一.安装 1 正确的安装方法: 众所周知,Linux系统自带的repo是不会自动更新每个软件的最新版本(基本都是比较靠后的稳定版),所以无法通过yum方式安装MySQL的高级版本.所以我们需要先安装带 ...
- 【面试题】Java常见面试题
集合与数组? 数组:(可以存储基本数据类型)是用来存储对象的一种容器,但是数组的长度固定,不适合在对象数量未知的情况下使用 集合:(只能存储对象,对象类型可以不一样)集合的长度可变,可在多数情况下使用 ...
- CF #579 (Div. 3) C.Common Divisors
C.Common Divisors time limit per test2 seconds memory limit per test256 megabytes inputstandard inpu ...
- Spark Streaming 入门
概述 什么是 Spark Streaming? Spark Streaming is an extension of the core Spark API that enables scalable, ...
- idea创建javaweb原生项目
使用idea创建javaweb项目 idea还是写框架项目比较爽,原生的javaweb项目不是特别方便,这篇文章就是记录一下创建的过程 图较多注意流量 选择创建web项目 配置tomcat服务器 配置 ...
- Python学习笔记整理总结【Django】:中间件、CSRF、缓存
一.中间件 中间件是一类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法:在django项目的settings模块中,有一个 MIDDLEWARE 变量,其中每 ...
- Spring 梳理-处理Multipart 请求
原理讲解 简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form method="post"actio ...
- 2019-ccpc秦皇岛现场赛
https://www.cnblogs.com/31415926535x/p/11625462.html 昨天和队友模拟了下今年秦皇岛的区域赛,,,(我全程在演 题目链接 D - Decimal 签到 ...
- 使用java的循环单向链表解决约瑟夫问题
什么是约瑟夫问题 据说著名犹太历史学家 Josephus有过以下的故事:在罗马人占领乔塔帕特后,39 个犹太人与Josephus及他的朋友躲到一个洞中,39个犹太人决定宁愿死也不要被敌人抓到,于是决定 ...
- 针对于ECMA5Script 、ECMAScript6、TypeScript的认识
什么是ECMAScript.什么又是ECMA? Ecma国际(Ecma International)是一家国际性会员制度的信息和电信标准组织.1994年之前,名为欧洲计算机制造商协会(European ...