You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

全局变量赋值后ID变更,为何未保持全局特性?

全局变量赋值后ID变化的疑惑

先看我写的代码:

初始全局变量定义:

ex = False
orig = id(ex)

两个测试函数:

def start(test):
    print("Start")
    global ex
    while True:
        if id(ex) == orig:
            print("same")
        else:
            print(orig)
            print(id(ex))

def end(test):
    print("End")
    global ex
    ex = True
    while True:
        if id(ex) == orig:
            print("same")
        else:
            print(orig)
            print(id(ex))

调用end函数时,里面的ex的ID和初始的orig完全不一样,但注释掉ex = True这行后,ID就和orig一致了。我本来以为global关键字的作用就是允许在函数里修改全局变量,实在搞不懂为什么赋值后ID会变。

问题本质解释

首先得搞清楚两个关键点:

  1. global关键字的作用:它是告诉Python,函数里的ex这个名字指向的是全局作用域里的变量,而不是创建一个局部的ex变量。它允许你修改全局变量的绑定关系,而不是修改变量指向的对象本身。
  2. Python的不可变对象特性:False和True都是不可变的布尔对象,而且Python会把它们做成单例——也就是说,整个程序里False只有一个实例,True也只有一个实例。

初始时,全局变量ex绑定的是False的实例,orig记录的就是这个实例的内存ID。当你执行ex = True时,并不是把原来的False对象改成True(不可变对象根本没法修改),而是把全局变量ex的绑定关系改了——让它指向True的实例。这时候id(ex)自然就是True实例的ID,和原来的orig肯定不一样。

如果是可变对象(比如列表),情况就不同:比如你定义ex = [],然后在函数里用global ex,再执行ex.append(1),这时候ex的ID不会变,因为你只是修改了列表对象内部的内容,没有改变ex的绑定关系——它还是指向原来那个列表实例。

关于函数中使用全局变量的补充说明

  • 若只是在函数内读取全局变量,不需要global关键字,Python会自动优先在局部作用域查找,找不到就去全局作用域找。
  • 若要在函数内给全局变量重新赋值(改变它指向的对象),必须用global声明,否则Python会把这个变量当作局部变量,执行时会报错(比如未赋值就引用)。
  • 对于可变对象,仅修改其内部元素(比如列表追加、字典改值)时,不需要global,因为这没有改变变量的绑定,只是修改了对象本身。

内容的提问来源于Stack Exchange,提问作者Skobo Do

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 22:50:21