基于Python闭包及其作用域详解

作者:pluviophile 时间:2023-11-07 07:22:02 

关于Python作用域的知识在python作用域有相应的笔记,这个笔记是关于Python闭包及其作用域的详细的笔记

如果在一个内部函数里,对一个外部作用域(但不是全局作用域)的变量进行引用,那么内部函数就被称为闭包(closure),而这个被内部函数引用的变量则被成为自由变量

闭包和函数调用没多少相关,而是关于使用定义在其他作用域的变量

命名空间和作用域

我们把命名空间看做一个大型的字典类型(Dict),里面包含了所有变量的名字和值的映射关系。在 Python 中,作用域实际上可以看做是“在当前上下文的位置,获取命名空间变量的规则”。在 Python 代码执行的任意位置,都至少存在三层嵌套的作用域:

最内层作用域,最先搜索,包含所有局部变量(Python 默认所有变量声明均为局部变量)

所有包含当前上下文的外层函数的作用域,由内而外依次搜索,这里包含的是非局部也非全局的变量

一直向上搜索,直到当前模块的全局变量

最外层,最后搜索的,内置(built-in)变量


scopes = {
"local": {"locals": None,
   "non-local": {"locals": None,
      "global": {"locals": None,
        "built-in": ["built-ins"]}}},
}

除了默认的局部变量声明方式,Python还有global和nonlocal两种类型的声明(nonlocal是Python3.x之后才有的),其中nonlocal是指最内层之外,global以内的变量。必须强调的是,最内层局部作用域对外层作用域的变量只有只读(read-only)的访问权限。比如下列的例子


x = 100
def main():
x += 1
print (x)
main()

UnboundLocalError Traceback (most recent call last)
<ipython-input-2-9ed43e483a17> in <module>()
 3 x += 1
 4 print(x)
----> 5 main()
<ipython-input-2-9ed43e483a17> in main()
 1 x = 100
 2 def main():
----> 3 x += 1
 4 print(x)
 5 main()
UnboundLocalError: local variable 'x' referenced before assignment

这里抛出UnboundLocalError,是因为main()函数内部的作用域对于全局变量x仅有只读权限,想要在main()中对x进行改变,不会影响全局变量,而是会创建一个新的局部变量,显然无法对还未创建的局部变量直接使用x += 1, 因为x未绑定到任何对象上。如果想要获得全局变量的完全引用,则需要global声明:


x = 100
def main():
global x
x += 1
print(x)
main()
print(x) # 全局变量已被改变

# result:
# 101
# 101

闭包

闭包和函数调用没多少相关,而是关于使用定义在其他作用域的变量。

看了上面的Python作用域规则后,我们可以仿照JavaScript写一个计数器的闭包:


"""
/* JavaScript Closure example */
var inc = function(){
var x = 0;
return function(){
console.log(x++);
};
};
var inc1 = inc()
var inc2 = inc()
"""

# Python
def inc():
x = 0
def inner():
 nonlocal x
 x += 1
 print(x)
return inner
inc1 = inc()
inc2 = inc()
inc1()
inc1()
inc1()
inc2()

# result:
# 1
# 2
# 3
# 1

在这里,全局环境下不能获取到inc()中的局部变量x的,但是我们返回了inc()内部函数inner(),而inner()对inc()中的局部变量是有访问权限的。也就是说inner()将inc()局部作用域打包发送给了inc1和 inc2,从而使他们各自独立拥有了一块封闭起来的作用域,不受其他运行环境和全局变量的影响,因此称之为闭包。

上述代码中inc1和inc2各自有一块封闭起来的作用域,可以通过Online Python Tutor 可视化运行工具看相应的运行结果

基于Python闭包及其作用域详解

这篇基于Python闭包及其作用域详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。

来源:http://www.cnblogs.com/pluviophile/archive/2017/08/27/7441851.html

标签:闭包,作用域,Python
0
投稿

猜你喜欢

  • python ftp 按目录结构上传下载的实现代码

    2021-01-28 00:38:33
  • python中利用numpy.array()实现俩个数值列表的对应相加方法

    2022-08-26 01:49:25
  • 编写Python脚本把sqlAlchemy对象转换成dict的教程

    2023-02-22 07:26:47
  • OpenCV 轮廓检测的实现方法

    2023-06-16 01:40:48
  • Pytorch中的 torch.distributions库详解

    2021-05-17 22:26:47
  • 高效的mysql分页方法及原理

    2024-01-20 04:23:46
  • 浅谈Python中的可变对象和不可变对象

    2021-07-17 16:58:49
  • Python读取Pickle文件信息并计算与当前时间间隔的方法分析

    2023-11-17 20:18:13
  • Python __all__变量用法示例详解

    2023-05-13 01:40:11
  • Jebrains付费插件Activation code[持续更新]

    2022-01-31 10:09:28
  • python+selenium+chromedriver实现爬虫示例代码

    2021-03-05 02:53:23
  • Python实现希尔排序算法的原理与用法实例分析

    2021-10-19 17:44:08
  • 对Python3之进程池与回调函数的实例详解

    2022-07-30 13:07:01
  • ASP中取得图片宽度和高度

    2009-11-08 18:39:00
  • 用ASP打开远端MDB数据库

    2007-10-13 06:56:00
  • 详解python程序中的多任务

    2021-01-10 18:55:37
  • 往MySQL中存储图片的方法

    2024-01-17 15:57:49
  • PHP中怎样防止SQL注入分析

    2023-08-16 04:45:35
  • 详解Python模块化编程与装饰器

    2023-06-30 19:49:07
  • vue中记录滚动条位置的两种方法

    2024-04-27 15:59:33
  • asp之家 网络编程 m.aspxhome.com