闭包的延迟加载

前言

闭包的延迟特性常常会在面试中考到,我之前面试也遇到过,虽然早就有所了解,但总是记不住。这里再写出来一下让自己长长记性

闭包的延迟简而言之就是闭包返回的内层函数不会立即执行, 而是在使用时候才执行
基于这个特性,内层函数如果使用了循环,同时使用到了循环计数值,则因其延迟特性,当使用到闭包时循环已经结束,所有的循环都已经结束,得到意料之外的结果


计算函数的执行结果

case1
def func():
    return [lambda x: x * i for i in range(5)]
    # func return [lambda x: x * 4, lambda x: x * 4, lambda x: x * 4, lambda x: x * 4, lambda x: x * 4]


print("func result:", [m(3) for m in func()])

>>>func result: [12, 12, 12, 12, 12]


# solve this problem: method1
def func2():
    return [lambda x, i=i: x * i for i in range(5)]
    # func2 return [lambda x: x * 0, lambda x: x * 1, lambda x: x * 2, lambda x: x * 3, lambda x: x * 4]


print("func2 result:", [m(3) for m in func2()])

>>>func2 result: [0, 3, 6, 9, 12]


# solve this problem: method2
def func3():
    for i in range(5):
        yield lambda x: x * i


print("func3 result:", [m(3) for m in func2()])

>>>func3 result: [0, 3, 6, 9, 12]


case2
def count():
    fs = []
    for i in range(1, 4):
        def c():
            return i * i

        fs.append(c)
    return fs  # fs = [c(), c(), c()]


f1, f2, f3 = count()  # 调用时i的for循环执行结束,i=3,c()=9
print("f1:", f1())
print("f2:", f2())
print("f3:", f3())

>>>f1: 9
>>>f2: 9
>>>f3: 9


# solve this problem
# 可以再创建一层函数, 加深深度, 以便于将循环变量与函数执行的变量隔开

def count2():
    def f(j):
        def g():
            return j*j
        return g
    fs = []
    for i in range(1, 4):
        fs.append(f(i)) # f(i)立刻被执行,因此i的当前值被传入f()
    return fs  # fs = [f(1), f(2), f(3)] = [1*1, 2*2, 3*3]

c1, c2, c3 = count2()
print("c1:", c1())
print("c2:", c2())
print("c3:", c3())

>>>c1: 1
>>>c2: 4
>>>c3: 9

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值