闭包(闭包=函数+环境变量)

本文探讨了闭包的概念,强调闭包是由函数和其定义时的环境变量组成,而非全局变量。通过实例解析了闭包的形成条件,指出经典误区,并利用闭包解决旅行者步数计数问题。示例中展示了如何从非闭包形式转换为闭包形式,以实现特定功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 扩充

  •  函数式编程(淡化)
  •  函数只是一段可执行的代码,不可以实例化,并不是对象
  •   一切皆对象、python    另外一个函数的参数,传递到另外的函数里;把一个函数当做是另一个函数的返回结果:
     
def a():
    pass
print(type(a))
#>>><class 'function'>

步入正题:闭包=函数+环境变量(函数定义时候的环境变量,不能是全局变量)

闭包是函数式编程的一种

1、闭包的形式及使用

#闭包
def curve_pre():
    b=25
    def curve(x):#曲线
        return b*x*x
    return curve

#curve()在外部不可以直接调用

b=10
f=curve_pre()
print(f.__closure__)#__closure__内置函数存放闭包的环境变量信息,返回的是闭包
#>>>(<cell at 0x0261B750: int object at 0x6DF7BFC8>,)

print(f.__closure__[0].cell_contents)
#>>>25   输出环境变量的值

f(2)#执行函数==>curve(2)
print(f(2))
#>>>100
#不会因为全局变量而输出40,而是使用环境变量a=25

__closure__内置函数存放闭包的环境变量信息,返回的是闭包

__closure__[0].cell_contents
#>>>25   输出环境变量的值

输出结果

>>> 
<class 'function'>
(<cell at 0x0261B750: int object at 0x6DF7BFC8>,)
25
100

 

延伸:单个函数f1(),a是全局变量,f1()函数在找不到a的值的情况下会调用全局变量a=10

a=10
def f1(x):
    return a*x*x
f1(2)
print(f1(2))
#>>>40

闭包的经典误区:

例子:

def f2():
    c=10
    def f3():
        c=20
        print(c)#②2>>>20
    print(c)#①1>>>10
    f3()
    print(c)#③3>>>10
f2()
    

输出结果:

>>>10
20
10

改动判断是不是闭包:

#改动判断是不是闭包
def f2():
    c=10
    def f3():
        #此时将被python认为是一个局部变量
        c=20
        return c
    return f3
w=f2()
print(w)
print(w.__closure__) #在这里这个属性__closure__是没有的 

输出:

>>><function f2.<locals>.f3 at 0x008AE030>
None

 重点!!!:在这里这个属性__closure__是没有的,其实因为c=20存在,它此时将被python认为是一个局部变量,内部函数输出的是局部变量而不是环境变量,不满足闭包的要求,所以实质上此时还不是一个闭包

再改进:

def f2():
    c=10
    def f3():
        #此时内部函数中只是引用了c
        d=20*c
        return c
    return f3
w=f2()
print(w)
print(w.__closure__)

输出:

<function f4.<locals>.f5 at 0x08896E88>
(<cell at 0x0371FB10: int object at 0x6DF7BED8>,)

此时根据print(w.__closure__)返回的信息(<cell at 0x0371FB10: int object at 0x6DF7BED8>,)得知是一个闭包

 

用闭包来解决一个问题:旅行者,每走一步加一,编写函数得到当前的位置

1、非闭包形式解决:

origin=0
def go(stpe):
    global origin
    new_pos=origin+stpe
    origin=new_pos
    return new_pos
    
print(go(2))#>>>2
print(go(3))#>>>5
print(go(6))#>>>11

2、闭包形式解决:

origin1=0
def factory(pos):  
    def go1(stpe):
        #强制声明pos不是局部变量
        nonlocal pos
        new_pos=pos+stpe
        pos=new_pos
        return new_pos
    return go1

tourist=factory(origin1)
print(tourist(2))#>>>2
print(origin1)#>>>0
print(tourist.__closure__[0].cell_contents)#>>>2
print(tourist(3))#>>>5
print(origin1)#>>>0
print(tourist.__closure__[0].cell_contents)#>>>5
print(tourist(6))#>>>11
print(origin1)#>>>0
print(tourist.__closure__[0].cell_contents)#>>>11

输出:
 

2
0
2
5
0
5
11
0
11

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值