Python:global、local与nonlocal变量

python,global,local,nonlocal,变量 · 浏览次数 : 130

小编点评

**程序代码:** ```python import numpy as npn def func(a): b = 1 return a + b print(func(n)) ``` **运行结果:** ``` 3 ``` **解释:** 1. `n` 是一个局部变量,在函数 `func`内被定义和赋值为 1。 2. `b` 是一个全局变量,在函数之外定义和赋值。 3. `func` 中使用了 `global`关键字对 `n` 进行访问,并修改了它的值。 4. 在 `print(func(n))` 中,`n` 是一个局部变量,由于 `func` 在函数外定义,因此无法直接访问全局变量 `n`。 5. `nonlocal` 关键字的作用是为 `n` 创建一个局部变量,并使用 `global`关键字访问全局变量。 6. 在 `print(func(n))` 中,`n` 是一个局部变量,由于 `func` 在函数外定义,因此无法直接访问全局变量 `n`。 **结论:** 该程序展示了局部变量、全局变量和非本地变量的使用场景,以及 `global` 和 `nonlocal`关键字如何用于访问和修改局部变量。

正文

1 local和global变量

先来看一个最简单的Python程序例子:

import numpy as np
n = 2
def func(a):
    b = 1    
    return a + b

print(func(n)) # 3

这里b声明在函数func内,则该变量拥有一个local scope(局部作用域,即在函数内),我们将这类变量称为local(局部)变量。

与之相对的npn这两个变量都在函数之外声明,也即它们都在gobal scope(全局作用域)中,我们将它们global(全局)变量。

如果我们使用IDE在return a+b处打断点并调试,那么可以看到IDE很方便地为我们展示了当前的局部和全局变量(以VSCode为例):

我们在local scope内也可以对global变量进行读取,如下所示:

n = 2
def func(a):
    b = 1    
    return a + b + n # 对全局变量进行读取

print(func(n)) # 5

然而,如果在local scope内对global变量进行修改,比如这样写:

n = 2
def func(a):
    n += 1 # 对全局变量进行修改
    b = 1    
    return a + b + n  
 
print(func(n)) 

运行到n+=1这一语句是就会抛出异常:

UnboundLocalError: local variable 'n' referenced before assignment

此时我们需要用global关键字在局部作用域内声明一个global变量,然后就可以自由修改该变量了:

n = 2
def func(a):
    global n
    n += 1
    b = 1    
    return a + b + n

print(func(n)) # 6

2 nonlocal 变量

最后,我们还要提一种变量,叫nonlocal变量。这种变量常用在局部嵌套函数中将外层函数中的自由变量绑定到内层函数作用域(事实上外层函数中的自由变量对于内层函数来说既也非local也非global,故名nonlocal)。如下列所示:

# outside function 
def outer():
    message = 'local'

    # nested function  
    def inner():

        # declare nonlocal variable
        nonlocal message

        message = 'nonlocal'
        print("inner:", message)

    inner()
    print("outer:", message)

outer()

打印输出:

inner: nonlocal
outer: nonlocal

可以看到,nonlocal的使用将外层函数作用域中的自由变量message和内层函数的作用域进行了绑定。

不过需要注意的是,如果我们使用global关键字来声明变量:

# outside function 
def outer():
    message = 'local'

    # nested function  
    def inner():

        # declare global variable
        global message

        message = 'nonlocal'
        print("inner:", message)

    inner()
    print("outer:", message)

outer()

那么最终的打印输出结果为:

inner: nonlocal
outer: local

这是因为global关键字的使用让我们在inner()函数(局部作用域)内声明了一个global变量,故如果我们在inner()函数内做任何修改,则修改的结果只会在局部作用域(也即outer()函数)之外出现。

此外,nonlocal还可以用来构建如下列所示的闭包函数func(参见我的博客《Python技法4:闭包和保存自由变量 》):

def sample():
    n = 0
    # 闭包函数
    def func():
        nonlocal n
        n += 1
        print("n =", n)
    return func

f = sample()
f() # n = 1
f() # n = 2

这里也是通过nonlocal关键字将自由变量与内层函数绑定,然后再对其进行修改的。

与Python:global、local与nonlocal变量相似的内容:

Python:global、local与nonlocal变量

声明在函数内的变量拥有一个local scope(局部作用域,即在函数内),我们将这类变量称为local(局部)变量。声明在函数之外的变量,也即它们都在gobal scope(全局作用域)中,我们将它们global(全局)变量。nonlocal变量常用在局部嵌套函数中将外层函数中的自由变量绑定到内层函数作用域。

[转帖]eval函数

https://www.cnblogs.com/chenyuting/p/12157711.html eval内置函数 eval是Python的一个内置函数,这个函数的作用是,把字符串当成有效的表达式来求值并返回计算结果。 1 eval(expression[, globals[, locals]]

SICP:求值和环境模型(Python实现)

一个环境就是帧(frame) 的一个序列,每个帧是包含着一些绑定(bindings) 的表格。这些约束将一些变量名字关联于对应的值(在一个帧内,任何变量至多只有一个绑定)。每个帧还包含一个指针,指向这个帧的外围环境(enclosing environment)。如果由于当前讨论的目的,将相应的帧看做是全局(global) 的,那么它将没有外围环境。一个变量相对于某个特定环境的值,也就是在这一环境中

音频文件降噪及python示例

操作系统 :Windows 10_x64 Python版本:3.9.2 noisereduce版本:3.0.2 从事音频相关工作,大概率会碰到降噪问题,今天整理下之前学习音频文件降噪的笔记,并提供Audacity和python示例。 我将从以下几个方面展开: noisereduce库介绍 使用Aud

Python按条件筛选、剔除表格数据并绘制剔除前后的直方图

本文介绍基于Python语言,读取Excel表格文件数据,以其中某一列数据的值为标准,对于这一列数据处于指定范围的所有行,再用其他几列数据的数值,加以数据筛选与剔除;同时,对筛选前、后的数据分别绘制若干直方图,并将结果数据导出保存为一个新的Excel表格文件的方法~

我从 Python 潮流周刊提取了 800 个链接,精选文章、开源项目、播客视频集锦

你好,我是豌豆花下猫。前几天,我重新整理了 Python 潮流周刊的往期分享,推出了第 1 季的图文版电子书,受到了很多读者的一致好评。 但是,合集和电子书的篇幅很长,阅读起来要花不少时间。所以,为了方便大家阅读,我打算将合集进一步整理,分门别类将原始内容的标题罗列出来。 本文总计约 800 个链接

从基础到高级应用,详解用Python实现容器化和微服务架构

本文分享自华为云社区《Python微服务与容器化实践详解【从基础到高级应用】》,作者: 柠檬味拥抱。 Python中的容器化和微服务架构实践 在现代软件开发中,容器化和微服务架构已经成为主流。容器化技术使得应用程序可以在任何环境中一致运行,而微服务架构通过将应用拆分成多个独立的服务,从而提升了系统的

Python循环控制

本文介绍了Python编程语言中关于for循环和if条件控制的一些基本使用。包含了单层循环的退出机制和多层循环的退出机制,使得我们在满足特定条件时,可以直接结束多层循环。

Python 潮流周刊#60:Python 的包管理工具真是多啊(摘要)

本周刊由 Python猫 出品,精心筛选国内外的 250+ 信息源,为你挑选最值得分享的文章、教程、开源项目、软件工具、播客和视频、热门话题等内容。愿景:帮助所有读者精进 Python 技术,并增长职业和副业的收入。 本期周刊分享了 13 篇文章,13 个开源项目,全文 2300 字。 重要提醒:

推荐一款Python接口自动化测试数据提取分析神器!

1、引言 在处理JSON数据时,我们常常需要提取、筛选或者变换数据。手动编写这些操作的代码不仅繁琐,而且容易出错。Python作为一个功能强大的编程语言,拥有丰富的库和工具来处理这些数据。今天,将介绍一个实用的Python库——JMESPath,它为提取JSON数据提供了简洁而强大的语法。 2、JM