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

Python多线程中同一对象实例变量内存地址差异原因咨询

问题描述

在运行类函数的多线程时使用了实例变量,查看该实例变量地址时发现index=3的线程中self.flag的地址与其他线程不同,疑惑同一对象中为何会存在该实例变量的两个内存地址。

代码示例
import time, threading, glob

class Test:
    def __init__(self):
        self.haha = 0
        self.flag = True

    def start(self, index):
        print("start thread index:", index, "self.flag:", self.flag)
        threading.Thread(target = self.create, args = (index, )).start()

    def stop(self):
        self.flag = False

        for i in range(1):
            time.sleep(1)
            if self.flag == True:
                print(True)
                return True
        print(False)
        return False

    def create(self, index):
        print("before go while loop", index,"self.flag", self.flag, "id", id(self.flag)
            , "id self:", id(self))
        while self.flag:
            print("in while loop", index,"self.flag", self.flag, "id", id(self.flag)
            , "id self:", id(self))
            time.sleep(3)
        
        self.flag = True


a = Test()
a.start(2)
print("Start index: 2")
temp = threading.Thread(target = a.stop)
temp.start()
temp.join()
print("Pre Start index: 3")
a.start(3)
print("After Start index: 3")
print("Pre Start index: 4")
a.start(4)
print("After Start index: 4")
运行结果
start thread index: 2 self.flag: True
before go while loop 2 self.flag True id 7333536 id self: 139774008739392
Start index: 2
in while loop 2 self.flag True id 7333536 id self: 139774008739392
False
Pre Start index: 3
start thread index: 3 self.flag: False
before go while loop 3 self.flag False id 7333504 id self: 139774008739392
After Start index: 3
start thread index: 4 self.flag: True
before go while loop 4 self.flag True id 7333536 id self: 139774008739392
in while loop 4 self.flag True id 7333536 id self: 139774008739392
in while loop 2 self.flag True id 7333536 id self: 139774008739392
问题解答

这是Python的布尔值缓存机制导致的,并非同一实例变量有两个内存地址:

  • 你打印的id(self.flag)是self.flag当前指向的布尔值对象的地址,而非实例变量本身的地址。从始终不变的id(self)能看出,实例对象的存储位置固定,self.flag作为对象属性的存储位置也固定,只是它指向的布尔值对象在变化。
  • Python会缓存常用的布尔值True和False,它们本身就是两个完全不同的对象,所以id自然不同。
  • 代码执行流程里:stop()方法把self.flag设为False,此时index=3的线程读取到的是False对象,所以id和其他线程的True不同;之后index=3线程执行完循环会把self.flag重新设为True,index=4线程读取到的就是缓存的True对象,id又和之前一致。

内容的提问来源于stack exchange,提问作者Nguyen Thanh Minh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.02 16:01:28