为何global更新变量无法同步线程内对象,调用对象方法却可以?
问题原因解析
先看你给出的代码场景:
import time import threading queue_variable = [] def thread_fn(queue_argument): while True: for i,e in enumerate(queue_argument): print(str(i)+". item: " + str(e)) time.sleep(5) def add_to_queue(*args): global queue_variable queue_variable = [*queue_variable, *args] # 原代码的`queue`应为笔误,修正为`queue_variable` x = threading.Thread(target=thread_fn, args=(queue_variable,), daemon=True) x.start()
调用add_to_queue(1,2,3)后全局queue_variable更新,但线程内队列未同步;换成queue_variable.append()的方式却能实现预期效果,核心原因在于Python的可变对象引用机制:
- 线程启动时,
queue_variable指向初始空列表的内存地址,这个地址被传递给线程的queue_argument参数——此时两者指向同一个列表对象。 - 用
queue_variable = [*queue_variable, *args]时,本质是创建了一个全新的列表对象,然后把全局变量queue_variable的引用切换到这个新对象上。但线程里的queue_argument仍然指向原来的空列表地址,自然看不到新内容。 - 而
append()操作是直接修改原列表对象本身:列表属于可变类型,append不会改变对象的内存地址,只是在原对象内部添加元素。线程里的queue_argument依然指向同一个对象,所以每次循环都能读取到最新元素。
你对global的误解:global仅用于让函数内的queue_variable指向全局作用域的变量,但它管不了对象的引用关系。你重新赋值的操作是让全局变量换了个对象,线程手里的还是旧对象,这和global本身无关。
内容的提问来源于stack exchange,提问作者shintuku
相关产品推荐
相关产品推荐

