闭包
day21
闭包:在内嵌函数中,首先必须是内部定义的函数,该函数包含对外部作用域而不是全局作用域名字的引用
如下例子:
x = 100 # 全局作用域名字 def f1(): x = 1 # x = 1 对f2而言就是外部作用域名字 y = 2 def f2(): print(x) y return f2 f = f1() print(f) # 得到的是f2的内存地址 f() # 这里输出结果是1,作用域在定义阶段就已经确立,跟调用的时候的位置没有关系 # tips: 可以使用 f.__closure__ 可说明就是闭包 print(f.__closure__) # 可得出一个元组,元素包括内部函数引用外部作用域的内存地址,f2没有返回结果则返回的None print(f.__closure__[0]) # 可得出元组中第一个元素的地址 print(f.__closure__[0].cell_contents) # 可得出第一个元素x的地址的值,输出为 1 print(f.__closure__[1].cell_contents) # 可得出第一个元素y的地址的值,输出为 2
输出结果:
<function f1.<locals>.f2 at 0x0000024794D398C8> 1 (<cell at 0x0000024794CA55B8: int object at 0x00000000648C60E0>, <cell at 0x0000024794CA55E8: int object at 0x00000000648C6100>) <cell at 0x0000024794CA55B8: int object at 0x00000000648C60E0> 1 2
举个例子(爬虫)来说明作用:
首先安装requests模块:
pip install requests
import requests print(requests.get("http://www.baidu.com")) # 得到返回值 <Response [200]> print(requests.get("http://www.baidu.com").text) # 得到页面的html代码
再次安装urlopen模块:
pip install urlopen
from urllib.request import urlopen def get(url): # print(url) # 得到传入的url http://www.baidu.com # print(urlopen(url)) # 得到内存地址 <http.client.HTTPResponse object at 0x000001784B748978> # print(urlopen(url).read()) # 得到html代码 return urlopen(url).read() # 返回html代码 print(get("http://www.baidu.com")) # 打印返回值 print(get("http://www.python.org")) # 打印返回值
爬python,要用的时候直接python()调用即可,对于使用者而言,不用关心里面的状态,对使用者隐藏。闭包函数除了返回函数体的功能外还包含对外部作用域的状态。
from urllib.request import urlopen def f1(url): def f2(): print(urlopen(url).read()) return f2 python=f1("http://www.python.org") python # 没加括号,不会使用 python() # 加上括号,开始调用使用
共有 0 条评论