前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python: 关键字nonlocal和global的区别

Python: 关键字nonlocal和global的区别

作者头像
Exploring
发布2022-09-20 14:07:35
8640
发布2022-09-20 14:07:35
举报
文章被收录于专栏:数据处理与编程实践

文章背景: Python中的变量,存在相应的作用域。根据作用域的不同,主要有局部变量全局变量非局部变量。关键字global用于定义全局变量,而关键字nonlocal用于定义非局部变量。

本文在查阅相关资料的基础上,对局部变量、全局变量和非局部变量进行了介绍,还对关键字globalnonlocal的使用场景进行了梳理。

1 局部变量

2 全局变量

3 非全局变量

1 局部变量

在函数体内或局部范围内声明的变量称为局部变量

(1) 通常,我们在函数内部声明一个变量以创建局部变量。

代码语言:javascript
复制
def foo():
    y = "local"
    print(y)

foo()

运行结果:

代码语言:javascript
复制
local

(2) 在函数外访问局部变量,程序将报错。

代码语言:javascript
复制
def foo():
    y = "local"

foo()
print(y)

运行结果:程序报错。

代码语言:javascript
复制
NameError: name 'y' is not defined

局部变量只在函数foo()或局部范围内工作。

2 全局变量

在函数外部或全局范围内声明的变量称为全局变量。这意味着可以在函数内部或外部访问全局变量。

Python中global关键字的基本规则是:

  • 当我们在函数内部创建变量时,默认情况下它是局部的。
  • 当我们在函数外部定义变量时,默认情况下它是全局的。您不必使用global关键字。
  • 我们使用global关键字在函数内部读写全局变量。
  • 在函数外使用global关键字无效。 (1) 从函数内部访问全局变量
代码语言:javascript
复制
c = 1   # 全局变量

def add():
    print(c)

add()

运行结果:

代码语言:javascript
复制
1

(2) 从函数内部修改全局变量

代码语言:javascript
复制
c = 1  # 全局变量

def add():
    c = c + 2  # increment c by 2
    print(c)

add()

运行结果:程序报错。

代码语言:javascript
复制
UnboundLocalError: local variable 'c' referenced before assignment

因为我们只能访问全局变量,而不能从函数内部对其进行修改。若要在函数内部修改,需要使用global关键字。

代码语言:javascript
复制
c = 1  # 全局变量

def add():
    global c
    c = c + 2  # increment c by 2
    print(c)

add()
print("c =", c)

运行结果:

代码语言:javascript
复制
3
c = 3

(3) 在嵌套函数中的全局变量

代码语言:javascript
复制
x = 5

def foo():
    x = 20

    def bar():
        global x
        x = 25

    print("在调用bar之前: ", x)
    print("调用bar")
    bar()
    print("在调用bar之后: ", x)

foo()
print("x在主体内: ", x)

运行结果:

代码语言:javascript
复制
在调用bar之前:  20
调用bar
在调用bar之后:  20
x在主体内:  25

存在同名变量时,python引用变量的顺序为:当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变量。

在调用函数bar()的前后,由于函数foo()中,局部变量x的存在,变量x接受局部变量的值,即x =20。此外,在函数bar()中,我们使用了global关键字创建了全局变量,因此,函数内部对x的修改,也会体现到函数foo()以外。所以,在调用函数foo()之后,x=25。

如果将函数foo()内的代码行x = 20去掉。修改后的代码块如下:

代码语言:javascript
复制
x = 5

def foo():

    def bar():
        global x
        x = 25

    print("在调用bar之前: ", x)
    print("调用bar")
    bar()
    print("在调用bar之后: ", x)

foo()
print("x在主体内: ", x)

运行结果:

代码语言:javascript
复制
在调用bar之前:  5
调用bar
在调用bar之后:  25
x在主体内:  25

在函数bar()中,我们使用了global关键字创建了全局变量。函数bar()内部对x的修改,也会体现到函数foo()内部。

3 非全局变量

(1) 非全局变量,通过关键字nonlocal来定义。只在闭包里面生效,作用域就是闭包里面的,外函数和内函数都影响,但是闭包外面不影响。

代码语言:javascript
复制
x = 0

def outer():
    x = 1
    def inner():
        nonlocal x
        x = 2
        print("inner:", x)

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

outer()
print("global:", x)

运行结果:

代码语言:javascript
复制
inner: 2
outer: 2
global: 0

在函数inner()内,我们使用了nonlocal关键字创建了非局部变量。函数inner()内部对x的修改,体现到了函数内部和函数outer()的内部,但函数outer()的外部不受影响。

(2) nonlocal的作用范围仅对于所在子函数的上一层函数中拥有的局部变量,必须在上层函数中已经定义过,并且不是非全局变量,否则报错。Nonlocal variable must be bound in an outer function scope.

代码语言:javascript
复制
def make_counter():
    count = 0

    def counter():
        nonlocal count
        count += 1
        return count
    return counter


test = make_counter()
print(test())
print(test())

运行结果:

代码语言:javascript
复制
1
2

在函数counter()内,我们使用了nonlocal关键字创建了非局部变量。

针对代码行test = make_counter(),这里将函数名counter赋给了变量test。因此,代码test(),本质上运行的是counter()。第一次运行test(),返回的count值是1。第二次运行test(),返回count值是2。

参考资料:

[1] Python 全局,局部和非局部变量(https://www.cainiaojc.com/python/python-global-local-nonlocal-variables.html

[2] Python Global 关键字(https://www.cainiaojc.com/python/python-global-keyword.html

[3] python关键字nonlocal和global的区别(https://www.jianshu.com/p/ab69b83a8d8a

[4] python nonlocal 和 global 的区别(https://www.cnblogs.com/kongzhongqijing/articles/14666653.html

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-03-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 数据处理与编程实践 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 局部变量
  • 2 全局变量
  • 3 非全局变量
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档