关于python:小手一抬学Python-Python-之闭包操作

6次阅读

共计 2069 个字符,预计需要花费 6 分钟才能阅读完成。

闭包,又叫做闭包函数、闭合函数,写法相似函数嵌套。

闭包的基本操作

从简单的概念中抽离进去,在 Python 中,闭包就是你调用一个函数 X,这个函数返回一个 Y 函数给你,这个返回的函数 Y 就是闭包。

把握任何技术前,都要先看一下最根本的案例代码:

def func(parmas):
    # 外部函数
    def inner_func(p):
        print(f"内部函数参数{parmas},外部函数参数{p}")

    return inner_func

inner = func("外")
inner("内")

对上述代码的阐明如下,在调用 func("外") 的时候产生了一个闭包 inner_func 函数,该闭包函数内调用了内部函数 func 的参数 parmas,此时的 parmas 参数被称为 自在变量(概念性名词,理解即可)。当函数 func 的申明周期完结后,parmas 这个变量仍然存在,起因就是被闭包函数 inner_func 调用了,所以不会被回收。

简略的进行闭包操作学习之后,你会发现闭包操作,在上篇博客曾经应用过了,博客的阐明的内容是 装璜器

再次对上文代码进行正文,帮忙你了解闭包函数的实现。

# 定义内部(外层)函数
def func(parmas):
    # 定义外部(内层)函数
    def inner_func(p):
        print(f"内部函数参数{parmas},外部函数参数{p}")
    # 肯定要返回内层函数
    return inner_func

# 调用外层函数,赋值给一个新变量 inner,此时的 inner 相当于内层函数,并且保留了自在变量 params
inner = func("外")
inner("内")

总结下来,实现一个闭包须要以下几步:

  1. 必须有一个内层函数;
  2. 内层函数必须应用外层函数的变量,不应用外层函数的变量,闭包毫无意义;
  3. 外层函数的返回值必须是内层函数。

闭包作用域

先看代码:


def outer_func():
    my_list = []

    def inner_func(x):
        my_list.append(len(my_list)+1)
        print(f"{x}-my_list:{my_list}")

    return inner_func

test1 = outer_func()
test1("i1")
test1("i1")
test1("i1")
test1("i1")

test2 = outer_func()
test2("i2")
test2("i2")
test2("i2")
test2("i2")

上述代码中的自在变量 my_list 的作用域,只跟每次调用外层函数,生成的变量无关,闭包每个实例援用的变量相互不存在烦扰。

闭包的作用

再上文中,你是否曾经对闭包的作用有初步理解了?
接下来再强调一下,闭包操作中会波及作用域相干问题,最终实现的指标是脱离了函数自身的作用范畴,局部变量还能够被拜访到。

def outer_func():

    msg = "幻想橡皮擦"
    def inner_func():
        print(msg)

    return inner_func

outer = outer_func()
outer()

如果你对滚雪球第一遍还有印象,会理解到局部变量仅在函数的执行期间可用,也就说 outer_func 函数执行过之后,msg 变量就不可用了,然而下面执行了 outer_func 之后,再调用 outer 的时候,msg 变量也被输入了,这就是闭包的作用,闭包实现了局部变量能够在函数内部拜访。
相应的实践再扩大一下,就是在该种状况下能够把局部变量当做全局变量用。

最初再备注一句,阐明一下闭包的作用吧:闭包,保留了一些非全局变量,即保留部分信息不被销毁。

判断闭包函数

通过 函数名.__closure__ 判断一个函数是否是闭包函数。

def outer_func():

    msg = "幻想橡皮擦"
    def inner_func():
        print(msg)

    return inner_func

outer = outer_func()
outer()
print(outer.__closure__)
(<cell at 0x0000000002806D68: str object at 0x0000000001D46718>,)

返回的元组中,第一项是 CELL 即为闭包函数。

闭包存在的问题

这个问题是地址和值的问题,是操作系统底层原理导致的问题,具体实现先看代码,一个十分经典的案例。

def count():
    fs = []
    for i in range(1, 4):
        def f():
            return i
        fs.append(f)
    return fs

f1, f2, f3 = count()
print(f1())
print(f2())
print(f3())

上述代码不是简略的返回了一个闭包函数,而是返回的一个蕴含三个闭包函数的序列 list
运行代码,输入 3 个 3,学过援用和值相干常识同学会比拟容易把握,上述代码中的 i 指向的是一个地址,而不是具体的值,这就导致当循环完结之后,i 指向那个地址的值等于 3

本案例你记住上面这句话也可。

尽量避免在闭包中援用循环变量,或者后续会发生变化的变量。

这篇博客的总结

本篇博客为大家补充了一下闭包相干的基础知识,配合上一篇装璜器博客一起学习,成果更加。

正文完
 0