前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >python:闭包

python:闭包

作者头像
用户7886150
修改2021-01-19 10:21:06
7290
修改2021-01-19 10:21:06
举报
文章被收录于专栏:bit哲学院bit哲学院

参考链接: Python闭包

闭包

 1.前言2.什么是闭包3.看一个闭包的实际例子:4.修改外部函数中的变量5.思考闭包与其他函数的区别

​ 假设我们需要做一个题目,是求y=kx+b这个一元一次函数在多个x上的值。 

1.前言 

第一种方法: 

# -*- coding: utf-8 -*-

# @Author  : summer

k = 1

b = 2

x = 0

print(k * x + b)

x = 1

print(k * x + b)

x = 2

print(k * x + b)

这个是最平常的一种写法,即直接定义一个k和一个b,然后写一个x,接着直接打印出y的值 

其实这个方法的缺点也可以看出–》代码冗余。那么代码冗余的话我们可不可以用函数解决呢? 

第二种:函数法 

# -*- coding: utf-8 -*-

# @Author  : summer

k = 1

b = 2

def create(x):

    print(k * x + b)  

create(1)

函数的方法虽然可以,但是如果代码过多,或者在create函数后面还有许多的函数,就可能导致全局变量k和b被修改导致结果出错,那有没有什么办法可以把变量存起来,让自己单独使用呢?没错就是面向对象方法 

第三种:面向对象法 

# -*- coding: utf-8 -*-

# @Author  : summer

class Create:

    def __init__(self, k, b):

        self.k = k

        self.b = b

    def __call__(self, x, *args, **kwargs):

        print(self.k * x + self.b)

c1 = Create(1, 2)

c1(1)

同样,上面的方法虽然可以把全局变量放入自己内部,但别忘了,创建对象时不知有现在所看到的两个魔法方法,每个对象默认调用object,因此你创建一个对象就会多出好多个没有的魔法方法,因此还有没有更好的方法呢?他来了—-闭包 

第四种:闭包 

# -*- coding: utf-8 -*-

# @Author  : summer

def test(k, b):

    def create(x):

        print(k * x + b)

    return create

t = test(1, 2)

t(1)

上面这种方法就是闭包,即函数里面再嵌套一层函数,并且最外层的函数返回值时内层函数的引用 

2.什么是闭包 

# 定义一个函数

def test(number):

    # 在函数内部再定义一个函数,并且这个函数用到了外边函数的变量,那么将这个函数以及用到的一些变量称之为闭包

    def test_in(number_in):

        print("in test_in 函数, number_in is %d" % number_in)

        return number+number_in

    # 其实这里返回的就是闭包的结果

    return test_in

# 给test函数赋值,这个20就是给参数number

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 line_conf(a, b):

    def line(x):

        return a*x + b

    return line

line1 = line_conf(1, 1)

line2 = line_conf(4, 5)

print(line1(5))

print(line2(5))

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

如果没有闭包,我们需要每次创建直线函数的时候同时说明a,b,x。这样,我们就需要更多的参数传递,也减少了代码的可移植性。 

注意点: 

由于闭包引用了外部函数的局部变量,则外部函数的局部变量没有及时释放,消耗内存 

4.修改外部函数中的变量 

def counter(start=0):

    def incr():

        nonlocal start

        start += 1

        return start

    return incr

c1 = counter(5)

print(c1())

print(c1())

c2 = counter(50)

print(c2())

print(c2())

print(c1())

print(c1())

print(c2())

print(c2())

这里使用一个nonlocal来声明start。和global差不多就是作用范围不同。 

5.思考闭包与其他函数的区别 

1.匿名函数能够完成基本的简单功能。传递的是这个参数的引用因此只有功能。 2.普通函数能够完成较为复杂的功能。传递的是这个函数的引用因此也只有功能。 3.闭包能后完成较为复杂的功能。传递的是这个闭包中的函数以及数据因此传递的是功能和数据。 4.对象能后完成最复杂的功能。传递的是很多数据+功能因此传递的是功能和数据。

本文系转载,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文系转载前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档