Python 如何访问外围作用域中的变量

yipeiwu_com7年前Python基础

在表达式中引用变量时,Python 会按照如下的顺序遍历各个作用域,寻找该变量:

  1. 当前函数作用域
  2. 任何外围作用域(比如包含当前函数的其他函数)
  3. global 作用域,即代码所在的模块的作用域

如果上述作用域内都找不到变量,就会报 NameError 异常。

但是对变量赋值时,规则会有所不同。

  1. 如果当前作用域变量已存在,那么其值会被替换。
  2. 如果不存在,则会视为在当前作用域定义新变量,而不是向外围作用域中寻找。

如下函数

def function():
  flag = True
  def helper():
    flag = False
  helper()
  print flag

function()

由于 helper 中变量是赋值,这里 flag 输出仍为 True。习惯了 c 语言之类静态类型语言,这种设计起初会感到困惑,但其可以有效地防止局部变量污染函数外的环境。

需求总是多样的,一定有程序员想在赋值时访问外围作用域。如果是 Python2,他可以这么做

def function():
  flag = [True]
  def helper():
    flag[0] = False
  helper()
  print flag

function()

先用 flag[0] 是读操作,产生一次变量引用,寻找到外围作用域中 flag,这时候再赋值 flag[0] = False 便不会新定义变量了。

如果是 Python3,则可以使用 nonlocal 关键字。

def function():
  flag = True
  def helper():
    nonlocal flag
    flag = False
  helper()
  print flag

function()

相关文章

wtfPython—Python中一组有趣微妙的代码【收藏】

wtfPython是github上的一个项目,作者收集了一些奇妙的Python代码片段,这些代码的输出结果会和我们想象中的不太一样; 通过探寻产生这种结果的内部原因,可以让我们对Pyth...

详解Pandas之容易让人混淆的行选择和列选择

详解Pandas之容易让人混淆的行选择和列选择

在刚学Pandas时,行选择和列选择非常容易混淆,在这里进行一下讨论和归纳 本文的数据来源:https://github.com/fivethirtyeight/data/tree/ma...

Python排序算法实例代码

Python排序算法实例代码

排序算法,下面算法均是使用Python实现: 插入排序 原理:循环一次就移动一次元素到数组中正确的位置,通常使用在长度较小的数组的情况以及作为其它复杂排序算法的一部分,比如mergeso...

kafka-python批量发送数据的实例

如下所示: from kafka import KafkaClient from kafka.producer import SimpleProducer def send_...

删除DataFrame中值全为NaN或者包含有NaN的列或行方法

如果存在以下DataFrame 年龄 性别 手机号 0 2 男 NaN 1 3 女 NaN 2 4...