python中的全局变量与局部变量的区别

本文通过五个示例详细解释了Python中全局变量与局部变量的区别,包括作用域、修改方式等,并介绍了如何正确使用global及nonlocal关键字。

原文链接,点击打开!!

全局变量与局部变量的本质区别在于作用域:

全局变量是在整个py文件中声明的,全局范围内都能访问;

局部变量是在某个函数中声明的,只能在该函数中调用它,如果试图在超出范围的地方调用,程序就会崩掉。

如果在函数内部定义某个与全局变量一样名称的局部变量,就可能导致意外的效果,不建议这样使用,这样会使程序不健全。

例1:

def fun(x):
    y=2
    print("乘法的运行结果:",x*y)

num1=1
print("初始num1=",num1)

fun(num1)

print("y的值是:",y)

运行结果:

初始num1= 1
乘法的运行结果: 2
Traceback (most recent call last):
  File "/home/python/Desktop/MX_Dynamic_Query_RTree2/test.py", line 18, in <module>
    print("y的值是:",y)
NameError: name 'y' is not defined

原因是:试图访问局部变量,但是访问的地方不在该变量y的作用域中,变量y是在函数内部定义的一个局部变量,所以该变量的作用域为该函数内部,在函数外部访问该局部变量y会报错!

例2:

def fun():
    num1 = 2
    print("函数内修改后num1=", num1)
num1 = 1
print("初始num1=", num1)
fun()

print("运行完函数后num1=", num1)

运行结果:

初始num1= 1
函数内修改后num1= 2

运行完函数后num1= 1

可以看到在函数内部对全局变量修改后,在函数执行完毕,修改的结果是无效的,全局变量并不会受到影响。

例3:

def fun():
    num1 *= 2
    print("函数内修改后num1=", num1)
num1 = 1
print("初始num1=", num1)
fun()

print("运行完函数后num1=", num1)

运行结果:

初始num1= 1
Traceback (most recent call last):
  File "/home/python/Desktop/MX_Dynamic_Query_RTree2/test.py", line 15, in <module>
    fun()
  File "/home/python/Desktop/MX_Dynamic_Query_RTree2/test.py", line 11, in fun
    num1 *= 2

UnboundLocalError: local variable 'num1' referenced before assignment

报错,这是因为在函数中使用了局部变量num1,它只是个跟全局变量同名的局部变量,使用前还是要赋值。

例4:如果真的想在函数体内修改全局变量的值,可以使用global关键字
def fun():
    global num1
    num1=2
    print("函数内修改后num1=",num1)
num1=1
print("初始num1=",num1)
fun()  

print("运行完函数后num1=",num1)

运行结果:

初始num1= 1
函数内修改后num1= 2
运行完函数后num1= 2

使用global关键字就是告诉python编辑器,这个变量不是局部变量而是全局变量,其实有点像"引用"的意思。

例5:关键字nonlocal,字面意思是当前这个变量不是局部变量,它是python3.0中新增的关键字,python2.x中不支持。

def fun():
    num2 = 3
    def fun2():
        num2 *= 2
        print("num2=", num2)
    return fun2()

fun()  

报错!!错误的原因跟前面的差不多,就是使用了未定义的局部变量,然而num2也不是全局变量,只是fun2函数的外层变量,强行使用global定义num2的话同样会报错。

加上nonlocal关键字:

def fun():
    num2 = 3
    def fun2():
        nonlocal num2
        num2 *= 2
        print("num2=", num2)
    return fun2()
fun()

运行结果:num2= 6

<think>好的,我需要回答用户关于Python全局变量局部变量区别的问题。用户已经提供了一些参考资料,我需要结合这些资料,并且参考之前的对话内容来组织回答。首先,用户之前的提问是关于类中能否使用外部变量,现在转向全局变量局部变量区别。我需要确保回答覆盖两者的定义、作用域、访问规则以及使用时的注意事项。同时,用户提供的引用内容提到了global关键字的作用、全局变量局部变量的使用场景,以及作用域的访问规则,这些都需要整合到回答中。接下来,我需要确定结构。通常,这样的问题适合分点回答,明确区别,可能包括定义、作用域范围、生命周期、修改方式等。此外,用户之前的回答中使用了表格总结,可能这次也可以用类似的方式,但需要根据当前问题调整内容。然后,要考虑用户可能的疑惑点,比如变量覆盖、修改全局变量的方法、嵌套作用域的处理等。引用中提到的在函数内部定义全局变量使用global关键字,以及局部变量的优先访问规则,这些都需要详细说明。还要注意引用标记的正确使用,确保每个引用的内容都对应正确的来源。例如,关于global关键字的作用来自引用[1],修改全局变量需要显式声明来自引用[4],函数参数作为局部变量的例子来自引用[4]等。另外,用户可能希望了解如何避免全局变量被意外修改,这在之前的回答中也有涉及,可以结合最佳实践来建议。同时,生成的相关问题需要主题紧密相关,比如作用域规则、global非local关键字的区别、变量覆盖等。最后,确保使用中文回答,数学公式代码块格式正确,引用标识自然添加,并生成相关问题。检查是否有遗漏的关键点,比如可变对象不可变对象在修改时的不同行为,或者闭包中的变量作用域问题,但这些可能超出当前问题范围,需根据资料决定是否包含。</think>### Python全局变量局部变量的核心区别 #### **1. 定义作用域** | 维度 | 全局变量 | 局部变量 | |--------------|------------------------------|------------------------------| | **定义位置** | 函数/类外部定义 | 函数/类内部定义 | | **作用范围** | 整个模块(跨函数访问) | 仅在定义它的函数/代码块内有效 | | **生命周期** | 随模块加载创建,程序结束销毁 | 随函数调用创建,返回后销毁 | **示例**: ```python global_var = 100 # 全局变量[^5] def test(): local_var = 200 # 局部变量 print(global_var) # 可读取全局变量[^4] test() # print(local_var) # 报错:NameError ``` --- #### **2. 访问修改规则** - **全局变量访问**: - 函数内可直接读取全局变量:`print(global_var)` - **修改需显式声明**:使用`global`关键字[^1][^3] ```python counter = 0 def increment(): global counter # 声明使用全局变量 counter += 1 # 允许修改[^4] ``` - **局部变量特性**: - 函数参数内部定义的变量均为局部变量 - **同名变量优先访问局部作用域**: ```python x = 10 def func(x): # 参数x是局部变量 print(x) # 优先访问局部x[^4] func(20) # 输出20 ``` --- #### **3. 关键差异对比** | 场景 | 全局变量 | 局部变量 | |--------------------|------------------------------|------------------------------| | 跨函数数据共享 | ✅ 直接实现 | ❌ 需通过参数传递 | | 内存占用 | 长期占用内存 | 临时创建,节省内存 | | 代码可维护性 | 易引发意外修改,维护困难[^2] | 作用域隔离,更安全 | | 修改方式 | 需`global`声明 | 直接赋值 | --- #### **4. 嵌套作用域的特殊情况** 在闭包或嵌套函数中,使用`nonlocal`可访问外层非全局变量: ```python def outer(): outer_var = "Python" def inner(): nonlocal outer_var # 声明访问外层变量 outer_var = "Java" inner() print(outer_var) # 输出: Java ``` --- ### **最佳实践建议** 1. **优先使用局部变量**:减少副作用,提高代码健壮性[^2] 2. **全局变量命名规范化**:如`GLOBAL_COUNTER`,提醒开发者谨慎修改 3. **避免直接修改全局变量**:通过函数返回值或类封装管理状态 4. **注意可变对象修改**: ```python global_list = [] def append_item(item): global_list.append(item) # 修改可变对象无需global声明[^3] ``` --- ### **常见问题解析** **Q1: 为何修改列表不需要`global`声明?** A1: 列表是可变对象,对其元素修改不改变变量指向的内存地址,因此不被视为"重新赋值"[^3] **Q2: 全局变量类属性的区别?** A2: 类属性通过`ClassName.attr`访问,具有命名空间隔离;全局变量直接暴露在模块作用域 --- ### 数学表达示例 局部变量的作用域可表示为: $$ \text{Scope}_{\text{local}} = \{ x \mid x \in \text{Function} \} $$ 而全局变量的作用域满足: $$ \text{Scope}_{\text{global}} = \text{Module} \setminus \bigcup \text{Scope}_{\text{local}} $$ ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值