博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Python高阶函数-闭包
阅读量:4328 次
发布时间:2019-06-06

本文共 2360 字,大约阅读时间需要 7 分钟。

高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。

在这里我们首先回忆一下python代码运行的时候遇到函数是怎么做的。

从python解释器开始执行之后,就在内存中开辟了一个空间

每当遇到一个变量的时候,就把变量名和值之间的对应关系记录下来。

但是当遇到函数定义的时候解释器只是象征性的将函数名读入内存,表示知道这个函数的存在了,至于函数内部的变量和逻辑解释器根本不关心。

等执行到函数调用的时候,python解释器会再开辟一块内存来存储这个函数里的内容,这个时候,才关注函数里面有哪些变量,而函数中的变量会存储在新开辟出来的内存中。函数中的变量只能在函数的内部使用,并且会随着函数执行完毕,这块内存中的所有内容也会被清空。

命名空间和作用域

命名空间一共分为三种:

  全局命名空间

  局部命名空间

  内置命名空间

*内置命名空间中存放了python解释器为我们提供的名字:input,print,str,list,tuple...它们都是我们熟悉的,拿过来就可以用的方法。

 

三种命名空间之间的加载与取值顺序:

加载顺序:内置命名空间(程序运行前加载)->全局命名空间(程序运行中:从上到下加载)->局部命名空间(程序运行中:调用时才加载)

取值:

  在局部调用:局部命名空间->全局命名空间->内置命名空间

1 x = 12 def f(x):3     print(x)4 5 print(10)

在全局调用:全局命名空间->内置命名空间

x = 1def f(x):    print(x)f(10)print(x)

作用域

作用域就是作用范围,按照生效范围可以分为全局作用域和局部作用域。

全局作用域:包含内置名称空间、全局名称空间,在整个文件的任意位置都能被引用、全局有效

局部作用域:局部名称空间,只能在局部范围生效

 

函数名的本质

函数名本质上就是函数的内存地址

1.可以被引用

def func():    print('in func')f = funcprint(f)

2.可以被当作容器类型的元素

def f1():    print('f1')def f2():    print('f2')def f3():    print('f3')l = [f1,f2,f3]d = {
'f1':f1,'f2':f2,'f3':f3}#调用l[0]()d['f2']()

3.可以当作函数的参数和返回值

*不明白?那就记住一句话,就当普通变量用

闭包

 

闭包函数:

 

内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数

#函数内部定义的函数称为内部函数

 

 

 

由于有了作用域的关系,我们就不能拿到函数内部的变量和函数了。如果我们就是想拿怎么办呢?返回呀!

 

我们都知道函数内的变量我们要想在函数外部用,可以直接返回这个变量,那么如果我们想在函数外部调用函数内部的函数呢?

 

是不是直接就把这个函数的名字返回就好了?

 

这才是闭包函数最常用的用法

def func():    name = 'eva'    def inner():        print(name)    return innerf = func()f()
#输出的__closure__有cell元素 :是闭包函数def func():    name = 'eva'    def inner():        print(name)    print(inner.__closure__)    return innerf = func()f()#输出的__closure__为None :不是闭包函数name = 'egon'def func2():    def inner():        print(name)    print(inner.__closure__)    return innerf2 = func2()f2()
def wrapper():    money = 1000    def func():        name = 'eva'        def inner():            print(name,money)        return inner    return funcf = wrapper()i = f()i()

 

from urllib.request import urlopendef index():    url = "http://www.xiaohua100.cn/index.html"    def get():        return urlopen(url).read()    return getxiaohua = index()content = xiaohua()print(content)

 

命名空间:

  一共有三种命名空间从大范围到小范围的顺序:内置命名空间、全局命名空间、局部命名空间

作用域(包括函数的作用域链):

小范围的可以用大范围的 但是大范围的不能用小范围的 范围从大到小(图)

在小范围内,如果要用一个变量,是当前这个小范围有的,就用自己的 如果在小范围内没有,就用上一级的,上一级没有就用上上一级的,以此类推。 如果都没有,报错

函数的嵌套:

  嵌套调用

  嵌套定义:定义在内部的函数无法直接在全局被调用

函数名的本质:

  就是一个变量,保存了函数所在的内存地址

闭包:

  内部函数包含对外部作用域而非全剧作用域名字的引用,该内部函数称为闭包函数

 

转载于:https://www.cnblogs.com/buyisan/p/7252423.html

你可能感兴趣的文章
Detours信息泄漏漏洞
查看>>
win32使用拖放文件
查看>>
Android 动态显示和隐藏软键盘
查看>>
raid5什么意思?怎样做raid5?raid5 几块硬盘?
查看>>
【转】how can i build fast
查看>>
null?对象?异常?到底应该如何返回错误信息
查看>>
django登录验证码操作
查看>>
(简单)华为Nova青春 WAS-AL00的USB调试模式在哪里开启的流程
查看>>
图论知识,博客
查看>>
[原创]一篇无关技术的小日记(仅作暂存)
查看>>
20145303刘俊谦 Exp7 网络欺诈技术防范
查看>>
原生和jQuery的ajax用法
查看>>
iOS开发播放文本
查看>>
20145202马超《java》实验5
查看>>
JQuery 事件
查看>>
main(argc,argv[])
查看>>
在线教育工具—白板系统的迭代1——bug监控排查
查看>>
121. Best Time to Buy and Sell Stock
查看>>
hdu 1005 根据递推公式构造矩阵 ( 矩阵快速幂)
查看>>
安装php扩展
查看>>