Python的闭包函数


 闭包函数

  基于函数对象的概念,可以将函数返回到任意位置去调用 ,但是作用域的关系是在定义完函数时就已经被确定了的,与函数的调用位置无关。

一、学习闭包函数的必备知识点:
闭包函数=名称空间与作用域+函数嵌套+函数对象
核心点:名字的查找关系是以函数定义阶段为准
二、什么是闭包函数?
闭:封闭关闭,封闭的函数。指的是该函数是内嵌函数,也就是说被麻袋装起来了
# 封闭的函数实例: # def f1(): # 这里的f1就是麻袋 # def f2(): # 这里的f2就是闭函数 # pass
    包:包住,在闭的基础上,指的是该函数f2包含对外层函数f1作用域名字的引用。(不是对全局作用域)
# 闭包函数实例1: # def f1(): # 这里的f1就是麻袋 # x = 1 # def f2(): # 这里的f2就是闭函数 # print(x) # 这里的x引用到了外层函数,所以此时的f2就是闭包函数 # f2() # x = 222 # f1() # 1

# 闭包函数实例2:闭包函数之名称空间与作用域+函数嵌套的应用 # def f1(): # 这里的f1就是麻袋 # x = 333333333333333333333 # def f2(): # 这里的f2就是闭函数 # print(x) # 这里的x引用到了外层函数,所以此时的f2就是闭包函数 # f2() # x = 222 # def foo(): # x = 444 # f1() # # foo() # 333333333333333333333

# 闭包函数实例3: # def f1(): # 这里的f1就是麻袋 # x = 333333333333333333333 # def f2(): # 这里的f2就是闭函数 # print(x) # 这里的x引用到了外层函数,所以此时的f2就是闭包函数 # f2() # x = 111 # def bar(): # x = 4444 # f1() # def foo(): # x = 2222 # bar() # # foo() # 333333333333333333333

# 闭包函数实例4:闭包函数之函数对象 # 思路:只要我拿到f2的内存地址,那么无论我到哪里调用都可以用到。 # 我想要在全局作用域拿到f2的内存地址。f2就可以在任意的地方调用了。
def f1(): x = 333333333333333333333
    def f2(): print("函数f2的x:",x) # print(f2) # 打印f2的内存地址
    return f2  # 这里注意不要加(),不加()拿到了内存地址 # 这里的f是全局变量,但是f的值来自局部,打破了层级上的限制。 
f = f1() # print(f) # 这里我可以获得到f2的内存地址,<function f1.<locals>.f2 at 0x0000025CC8499670>

# 拿到了f2的内存地址后加括号执行得到结果 # f() # 运行结果:函数f2的x: 333333333333333333333

def foo(): x = 555 f() foo() # 函数f2的x: 333333333333333333333

三、闭包函数的应用场景?(为什么要有闭包函数?)
# 四、两种为函数体传参的方式 # 1、方式一:直接把函数体需要的参数定义成形参,直接传参 # def f2(x): # print(x) # f2(1) # f2(2) # f2(3)

# 2、方式二:使用闭包函数 # def f1(): # 包的效果 # x = 3 # def f2(): # print(x) # return f2 # 返回f2的内存地址,把f2内存地址放到全局 # # f = f1() # print(f) # 获得到了f2的内存地址:<function f1.<locals>.f2 at 0x0000013A25559670> # f() # 3

# 把上面的函数写活,修改函数体的参数
def f1(x):  # 包的效果
    # x = 3 # 这样就写死了,如何写活?
    def f2(): print(x) return f2  # 返回f2的内存地址,把f2内存地址放到全局
 f = f1(3) print(f)  # 获得到了f2的内存地址:<function f1.<locals>.f2 at 0x0000013A25559670>
f()  # 3
# 爬取三个网址的信息 # import requests # response = requests.get("https://www.baidu.com") # print(response.text) # requests.get("https://www.cnblogs.com/liunaixu/") # print(response.text) # requests.get("https://www.cnblogs.com/linhaifeng/") # print(response.text)

# 优化上面代码:写一个下载的功能, # 传参的方案一: # import requests # def get(url): # # response = requests.get("https://www.baidu.com") # # print(response.text) # response = requests.get(url) # print(len(response.text)) # get("https://www.baidu.com") # get("https://www.cnblogs.com/liunaixu/") # get("https://www.cnblogs.com/linhaifeng/")

# 使用闭包函数:方案二
import requests def outter(url): # url='https://www.baidu.com' # 不能写死
    def get(): response = requests.get(url) print(len(response.text)) return get baidu = outter('https://www.baidu.com')   # 拿到outter的内存地址
baidu() bokeyuan = outter('https://www.cnblogs.com/liunaixu/') bokeyuan()

 

# 四、验证closures()函数
x = 1
def outer(): x = 2
    def inner(): print(x) return inner func = outer() func() # 2 # 可以通过函数的closure属性,查看到闭包函数所包裹的外部变量
print(func.__closure__) # (<cell at 0x000002A01FB86B80: int object at 0x00007FFADB77D6C0>,)

 

 


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM