Python

😀
 

1. 四种作用域

Python 中有四种作用域,分别是:
  1. Local(局部作用域)
  1. Enclosing(外层作用域)
  1. Global(全局作用域)
  1. Built-in(内建作用域)
当访问一个变量时,Python 会按以下顺序查找: Local => Enclosing => Global => Built-in
notion image
上述图示的详细分析,请参考视频教程。

1.1. 局部作用域(Local)

定义:函数的内部就是局部作用域,局部作用域中的变量,只在该函数内部可见。
特点:
  • 每次调用函数都会创建一个新的局部作用域。
  • 函数运行结束后,局部作用域会随之销毁。
  • 局部作用域优先级最高,即:查找一个变量时,Python 会首先在局部作用域中查找。
举例:

1.2. 外层作用域(Enclosing)

定义:如果函数中又定义了函数,那么外层函数的作用域,就是内层函数的 Enclosing 作用域。
特点:
  • 只有当函数“嵌套定义”时才会出现。
  • 内层函数可以读取外层函数变量。
  • 想修改外层变量必须使用nonlocal
举例:
修改外层变量:

1.3. 全局作用域(Global)

定义:.py文件就是全局作用域,全局作用域中的变量,在当前.py文件的任何位置都可以访问。
特点:
  • 全局变量只在当前.py文件中可见。
  • 函数内部可以使用global关键字修改全局变量。
例子:
如果要修改:

1.4. 内建作用域(Built-in)

定义:Python 预先定义好的东西,会放在内建作用域中,所有.py文件都可以直接使用。
特点:
  • 所有.py文件都能直接使用其中的名称。
  • 例如:printlenrangesummax 等。
  • 查找优先级最低,即:查找一个变量时,内建作用域是“最后一道防线”。
例子:

2. 闭包

2.1. 前置知识

前置知识 1: 局部作用域的生命周期。
  • 每次调用函数时,都会创建一个新的局部作用域。
  • 函数执行完毕后,该作用域就会被销毁,其中的局部变量,也会随之释放。
在上述代码中:每次调用 outer()num 都会重新生成,不会保存上一次的值。
前置知识 2:内层函数访问外层变量。
  • 【内层函数】可以访问到【外层函数】作用域中的变量。
  • 访问外层变量不用nonlocal,修改外层变量时要使用nonlocal
如下代码验证了:理论上num变量应该在outer函数调用完销毁,但实际并没有。

2.2. 什么是闭包

  • 闭包 = 内层函数 + 被内层函数引用的外层变量。
  • 产生闭包的三个条件如下:
  1. 必须有函数嵌套
  1. 内层函数使用了外层函数的变量
  1. 外层函数返回内层函数

2.3. 闭包的基本形式

在上述代码的基础上,我们在inner函数中不仅要打印num,还要去修改num(修改时记得加上nonlocal num)。最终发现:num的值居然还可以一直增加,所以截至目前,证明了一件事:本应该随着outer函数调用结束而死去的num,并没有死去,并且inner函数依然可以对num进行读取和修改。所以我们观察如下的代码形式,完全符合上述的闭包产生条件,所以此时就出现了闭包

2.4. 闭包是如何保存外层变量的?

外层变量会被保存到 闭包单元(cell)中,例如下面代码中,那些被 inner函数所使用到的outer函数中的局部变量,会被封存在闭包单元(cell) 中,这些cell组成一个 __closure__ 元组,保存在了inner函数上。
思考:内层函数inner会保存外层函数outer中所有的数据吗? 不会,只会保存inner中所用到的。

2.5. 注意点

1. 每次获得一个新闭包,互不影响(闭包之间是互相独立的)。
  1. 外层变量为可变对象时仍互不影响。

2.6. 闭包的优点

  1. 可以“记住”状态:不用全局变量,也不用写类,就能在多次调用之间保存数据。
  1. 可以做“配置过的函数”:先传一部分参数,把环境固定住,得到一个定制版函数。
  1. 可以实现简单的“数据隐藏”:外层变量对外不可见,只能通过内层函数访问。
  1. 是装饰器(decorator)等高级用法的基础。
小案例:使用闭包实现对文字的美化效果。

2.7. 闭包的缺点

  1. 理解成本较高:对初学者不太友好,滥用会让代码难读。
  1. 如果闭包里引用了很大的对象,又长期不释放,可能会增加内存占用。
  1. 很多场景下,其实用【类 + 实例属性】会更清晰,闭包不一定是最优解。
例如将上述的文字美化效果,用类实现:

3. 装饰器

📎 参考文章

  • 一些引用
  • 引用文章
 
💡
欢迎您在底部评论区留言,一起交流~
上一篇
第一节 大脑:重新认识你自己
下一篇
临时
Loading...