说说 Python 的变量作用域

港控/mmm° 2022-10-29 09:03 294阅读 0赞

先来看一个示例:

  1. def f1(a):
  2. logging.info('a -> %s', a)
  3. logging.info('b -> %s', b)
  4. logging.info('f1(3) -> %s',f1(3))

运行结果:
3176aae0c9039a71b1fc64fb5259bb71.png

因为 b 没有定义,所以在运行 f1() 函数时抛错了。

在 pycharm 中也会以红色波浪形式提示我们这个变量还未定义:
ed7bdd459216082f6f4e286b15e625e9.png

解决这个问题也很简单,先定义好变量 b 即可:

1821ca5b9b71d2d8da5ef671654180d3.png

输出结果:
3eeb616951189bfefcd1ff7faebfd598.png

因为我们没有为 f1() 函数定义返回值,所以f1() 函数的输出为 None。

我们在 f1() 函数内部对 b 进行赋值操作,结果令人意外:
46dc4379095666931d2446ef5f1ada1e.png

输出结果:
2ebe09ddc2a868f032337af57b7219d7.png

pycharm 也以红色波浪线提醒我们这里的 b 变量存在问题。

通过 dis 模块,我们可以查看 Python 函数的字节编码:

  1. from dis import dis
  2. logging.info('dis(f1) -> %s',dis(f1))

运行结果:
61292b923ce3a97a9b45007837bc60b0.png

从字面码中可以看出,变量 a 与 b 都是从局部作用域(LOAD_FAST)中加载。而变量 b 在使用前没有被初始化,所以抛错。

可以通过把变量 b 定义为 global,来修复上述代码:

0d88faad83c623bc3a6a503fe1591dc5.png

这时的变量 b 就会从全局作用域中加载,所以运行正常:
0ce35437471a28383fb69f25dea22914.png


Luciano Ramalho (作者),安道,吴珂 (译者).流畅的Python[M].人民邮电出版社,2017:308-311.

发表评论

表情:
评论列表 (有 0 条评论,294人围观)

还没有评论,来说两句吧...

相关阅读

    相关 Python变量作用

    Python程序有各种各样的命名空间,它指的是在该程序段内一个特定的名称是独一无二的,它和其它同名的命名空间是无关的。 在Python中每一个函数都有自己的命名空间,如果在函