写点什么

python 小知识 -python 作用域和闭包

  • 2022 年 6 月 09 日
  • 本文字数:1191 字

    阅读完需:约 4 分钟

python小知识-python作用域和闭包


1. 不一样的作用域

python 常规的变量的作用域和其他语言没有什么大的区别,但 python 解释器在确认变量有效作用域也有些不同。


我们来看一个例子:


a = 10b = 5def func():    c = 1    print(a)    print(c)    print(b)
b = 1
func()
复制代码


从上面例子我们可以知道ab是全局变量,cfunc中局部变量,abfunc中可见。


但是上面代码执行有问题吗? 有,为什么会报b是未定义。这是因为:func中有定义了局部变量b,python 解释器在就会认为b是局部变量(替换了前面的全局变量),这样就会出现赋值之前打印报错情况。


为什么会这样? 只能说是 python 的设计原则,让开发者不要同名的全局和局部变量混淆导致混乱的局面。


UnboundLocalError                         Traceback (most recent call last)<ipython-input-2-b85674dbf69f> in <module>()      9     b = 1     10 ---> 11 func()
<ipython-input-2-b85674dbf69f> in func() 5 print(a) 6 print(c)----> 7 print(b) 8 9 b = 1
UnboundLocalError: local variable 'b' referenced before assignment
复制代码


要怎么破?python 给了一个 global 的关键字,来定义变量在局部区域还是全局性变量。


a = 10b = 5def func():    print('a =', a)    global b    print('b =', b)    b = 1
func()print('a =', b)
# a = 10# b = 5# a = 1
复制代码


增加了global b明确了 b 的作用域范围,外部也可以访问,而且可以修改。

2. 闭包

闭包 (closure)在其他语言如 js,java,go 中出现,特别是函数式编程语言 Groovy,scala Lisp 等。python 同样支持闭包。


到底什么是闭包?


简单的说,闭包是函数中函数即嵌套函数,和装饰器一样。可能还是比较抽象,这里给闭包做一个概念:在一个内部函数中,对外部作用域的变量进行引用,(并且一般外部函数的返回值为内部函数),那么内部函数就被认为是闭包。


我们来看一个例子:


def make_avg():    data = []    def avg(value):        data.append(value)        return sum(data)/len(data)    return avg
avg = make_avg()
print(avg(10))print(avg(20))print(avg(30))
# 10.0# 15.0# 20.0
复制代码


按照上面的例子,我们可以叫函数 avg 是闭包。同时我们可以得出闭包的两个特点(特别重要,请记住)


  • 嵌套函数,内部的函数为闭包,同时一般内部函数作为外部函数的返回值

  • 闭包(即内部函数)能访问外部函数的作用域内的变量引用(这就是上面的作用域)


上面的例子的功能是实现输入的累计均值。每次执行时都会把传入值存入外部作用域的变量中,只要avg = make_avg()没有消亡,不断添加的数据都是存在。有没有 get 到闭包的好处?


  • 闭包最大的好处是保存运行环境(指的是外部引用)


这种功能可以用在需要保存当前状态的功能中,状态有会不断的更新。而通常我们可能会写一个类来完成这个功能,即将状态作为类的属性。闭包也可以完成这个功能,相对来说更简单。





发布于: 刚刚阅读数: 3
用户头像

公众号:人工智能微客(weker) 2019.11.21 加入

人工智能微客(weker)长期跟踪和分享人工智能前沿技术、应用、领域知识,不定期的发布相关产品和应用,欢迎关注和转发

评论

发布
暂无评论
python小知识-python作用域和闭包_Python_AIWeker-人工智能微客_InfoQ写作社区