python面向对象进阶-闭包

本文深入探讨Python中的闭包概念,通过实例解析闭包的定义、工作原理及其实用场景。闭包允许内部函数访问并保留外部函数的局部变量,增强了代码的复用性和封装性。文中通过line_conf函数展示了如何利用闭包创建可定制的数学函数,体现了闭包在减少参数传递、提升代码可移植性方面的优势。
摘要由CSDN通过智能技术生成


前言

学习python的闭包概念


1. 函数引用

先看个函数的引用情况

def test1():
    print("--- in test1 func----")


# 调用函数
test1()

# 引用函数
ret = test1

print(id(ret))
print(id(test1))

# 通过引用调用函数
ret()

运行结果

--- in test1 func----
1937642892960
1937642892960
--- in test1 func----

可以看出,引用函数,然后调用,和直接调用函数,实际是调用的同一个方法体


2. 什么是闭包

# 定义一个函数
def test(number):
    # 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包
    def test_in(number_in):
        print("in test_in 函数, number_in is %d" % number_in)
        return number + number_in

    # 其实这里返回的就是闭包的结果
    # 注意,这里返回是test_in 函数体的位置,接收这个参数后,可以直接()调用之前写好的test_in方法
    # 这里返回不能加上(),加上后就是返回调用test_in函数的返回值,会报错,缺少number_in参数
    return test_in


# 给test函数赋值,这个20就是给参数number,并且ret指向了test_in这个函数体的位置
ret = test(20)

# 注意这里的100其实给参数number_in
print(ret(100))

# 注意这里的200其实给参数number_in
print(ret(200))

运行结果

in test_in 函数, number_in is 100
120
in test_in 函数, number_in is 200
220

3. 闭包再理解

内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。

def counter(start=0):
    count = [start]

    def incr():
        count[0] += 1
        return count[0]

    return incr


# c1指向 incr的函数体,并保存了外部函数的变量count=[5]
c1 = counter(5)
print(c1())	# 等价于incr(),又因为之前保存了count变量值,所以调用的时候自带count值,并进行修改
print(c1())

# c2也指向 incr的函数体,并保存了外部函数的变量count=[100]
c2 = counter(100)
print(c2())
print(c2())

print(c1())
print(c1())

print(c2())
print(c2())

运行结果

6
7
101
102
8
9
103
104

4. 看一个闭包的实际例子

内部函数对外部函数作用域里变量的引用(非全局变量),则称内部函数为闭包。

def line_conf(a, b):
    def line(x):
        return a * x + b

    return line


line1 = line_conf(1, 1)	# 调用line_conf方法,并因为line1指向了内部函数line,所以a,b的值还保存
line2 = line_conf(4, 5)	# 调用line_conf方法,并因为line2指向了内部函数line,所以a,b的值还保存
print(line1(5))	# 调用line函数,并传入x的值
print(line2(5))

运行结果

6
25

这个例子中,函数line与变量a,b构成闭包。在创建闭包的时候,我们通过line_conf的参数a,b说明了这两个变量的取值,这样,我们就确定了函数的最终形式(y = x + 1和y = 4x + 5)。我们只需要变换参数a,b,就可以获得不同的直线表达函数。由此,我们可以看到,闭包也具有提高代码可复用性的作用。
如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。

闭包思考

1.闭包似优化了变量,原来需要类对象完成的工作,闭包也可以完成
2.由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值