Python变量作用域(全局变量与局部变量)及命名空间

本文介绍了Python中的变量作用域,分为全局变量和局部变量。全局变量在函数外部定义,全程有效;局部变量在函数内部定义,仅在函数内部有效。在函数内使用全局变量需使用`global`关键字。接着,文章详细讲解了命名空间,包括其解释和查找顺序,指出Python程序中有局部命名空间、全局命名空间和内置命名空间,并提到了`globals()`和`locals()`函数的作用。
摘要由CSDN通过智能技术生成

Python变量作用域(全局变量与局部变量)及命名空间

全局变量和局部变量

Python 中的变量并不是无论在哪个位置都可以访问的,访问权限取决于这个变量是在哪里赋值的。变量的作用域决定在哪一部分程序中可以访问哪个特定的变量。

根据变量作用域的不同,可把变量分为两种基本类型:全局变量局部变量

全局变量:指在函数之外定义的变量,在程序执行全过程有效。一般没有缩进。

局部变量:指在函数之内定义的变量,仅在函数内部有效,当函数使用过后,变量从内存中释放(即变量将不再存在)。例如:

a = 1  # a 为全局变量
def calc():
    b = a + 3  # b 为全局变量
    print(b)
    
calc()
>>> 4

print(b)
>>> NameError       Traceback (most recent call last)
<ipython-input-3-67e500defa1b> in <module>
----> 1 print(b)

NameError: name 'b' is not defined
n = 1
def calc(a,b):
    n = b
    return a + b
s = calc(5,4)
print(s,n)
>>> 9 1

从上面代码可知,函数 calc() 使用了变量 n ,且将参数 b 赋值给变量 n ,函数 calc() 有自己的内存空间,n = b 实际上是重新生成的局部变量,此时函数并没有将 n 看做全局变量 n 。当函数退出时,局部变量 n 被释放,全局变量的值没有改变。

如果要在函数中使用全局变量,只需要在函数内部的变量前加上关键字 global 。例如:

n = 1
def calc(a,b):
    global n   # 使用 global 声明 n 为全局变量
    n = b
    return a + b
s = calc(5,4)
print(s,n)
>>> 9 4

命名空间

命名空间的解释

作用域是指 Python 程序可以直接访问到的命名空间。

命名空间本质上是一个字典,它的键就是变量名,它的值就是变量的值。Python 使用命名空间来记录变量的轨迹。

在Python程序中的任何一个地方,都存在三个可用的命名空间。

(1)每个函数都有自己的命名空间(称作局部命名空间),它记录了函数中的变量,包括函数的参数和定义的局部变量。

(2)每个模块都有自己的命名空间(称作全局命名空间),它记录了模块中的变量,包括函数、类、其他导入的模块、模块级的变量和常量。

(3)每个模块都有可访问的内置命名空间,它存放着内建函数和异常。

命名空间的查找顺序

当一行代码要使用变量 x 的值时,Python 会到所有可用的命名空间去查找变量,其查找顺序如下。

(1) 局部命名空间——特指当前函数或类的方法。如果函数中定义了一个局部变量 x,Python 将使用这个变量,然后停止搜索。

(2)全局命名空间——特指当前的模块。如果模块中定义了一个名为 x 的变量、函数或类,Python 将使用它,然后停止搜索。

(3)内置命名空间——对每个模块都是全局的,作为最后的尝试,Python 将假设 x 是内建函数或变量。

(4)如果 Python 在这些命名空间中都找不到 x,它将放弃查找并引发一个NameError 异常,同时传递 There is no variable named‘x’ 这样一条信息。

当函数被调用时,创建一个局部命名空间,可以通过 globals() 和 locals() 两个内建函数判断某一名字属于哪个名称空间,locals() 是只读的,globals()不是。

def foo(arg, a):
    x = 1
    y = 'abc'
    for i in range(5):
        j = 2
        k = i
    print(locals())

foo(2,3)
>>> {'arg': 2, 'a': 3, 'x': 1, 'y': 'abc', 'i': 4, 'j': 2, 'k': 4}

locals() 实际上没有返回局部命名空间,它返回的是局部命名空间的一个拷贝,所以对它进行改变时,对局部命名空间的变量值并无影响。

var = globals()
print(var)

而 globals() 函数返回实际的全局命名空间,不是它的一个拷贝。所以对 globals() 函数所返回的 var 的任何改动都会直接影响到全局变量。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值