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

如何将变量传递到不同函数并修改该变量?

这个问题核心是变量作用域和多线程安全的问题——你写的伪代码里members是on_start()的局部变量,function1()和function2()根本访问不到,肯定会报NameError。下面给你几种实用的解决方案,按场景选就行:

解决方案1:使用全局变量+线程锁

如果是小型脚本,全局变量是最直接的方式,但因为你提到function1()在独立线程运行,必须加锁避免多线程同时读写字典导致的竞态条件(比如读的时候刚好在写,数据会乱)。

import threading
import time
from threading import Lock

# 全局变量存储成员,搭配锁保证线程安全
members = {}
members_lock = Lock()

def on_start():
    global members
    # 初始化字典
    members.update({'guy1':'1234','guy2':'5678'})

def function1():
    # 读取前加锁,确保读取过程中不会被修改
    with members_lock:
        print("当前成员键:", list(members.keys()))

def function2(new_member):
    # 修改前加锁,避免多线程同时修改导致数据异常
    with members_lock:
        members.update(new_member)
        print(f"已添加新成员:{new_member}")

def run_function1():
    # 模拟独立线程循环执行function1
    while True:
        function1()
        time.sleep(2)

if __name__ == "__main__":
    on_start()
    # 启动function1的线程,daemon=True表示主线程结束时自动退出该线程
    threading.Thread(target=run_function1, daemon=True).start()
    
    # 模拟触发"add_member"事件
    time.sleep(3)
    function2({'guy3':'9012'})
    time.sleep(3)
    function2({'guy4':'3456'})

优缺点:简单易上手,但全局变量会让代码耦合度变高,大型项目里不好维护;锁必须严格对应,不然还是会出问题。

解决方案2:面向对象封装(推荐)

如果是中大型项目,用类把成员字典和操作它的方法封装在一起,是更规范的做法——状态(members)和行为(function1/function2)绑定,代码结构清晰,锁也可以封装在类内部,不容易出错。

import threading
import time
from threading import Lock

class MemberManager:
    def __init__(self):
        # 实例属性存储成员,每个实例独立
        self.members = {}
        self.lock = Lock()
    
    def on_start(self):
        # 初始化成员
        self.members.update({'guy1':'1234','guy2':'5678'})
    
    def function1(self):
        with self.lock:
            print("当前成员键:", list(self.members.keys()))
    
    def function2(self, new_member):
        with self.lock:
            self.members.update(new_member)
            print(f"已添加新成员:{new_member}")

def run_function1(manager):
    while True:
        manager.function1()
        time.sleep(2)

if __name__ == "__main__":
    # 创建实例
    manager = MemberManager()
    manager.on_start()
    
    # 把实例传给线程,让线程可以调用实例方法
    threading.Thread(target=run_function1, args=(manager,), daemon=True).start()
    
    # 模拟触发事件
    time.sleep(3)
    manager.function2({'guy3':'9012'})
    time.sleep(3)
    manager.function2({'guy4':'3456'})

优缺点:代码模块化,易维护、易扩展(比如后续加删除成员的方法,直接在类里加就行);完全避免全局变量,多线程安全更有保障,是工业级代码的常用写法。

解决方案3:参数传递(无全局变量)

如果不想用全局变量或类,也可以把members和锁作为参数传递给各个函数——因为字典是可变对象,传递的是引用,修改函数里的字典会直接影响原对象。

import threading
import time
from threading import Lock

def on_start():
    # 初始化字典和锁,返回给调用者
    members = {'guy1':'1234','guy2':'5678'}
    return members, Lock()

def function1(members, lock):
    with lock:
        print("当前成员键:", list(members.keys()))

def function2(members, lock, new_member):
    with lock:
        members.update(new_member)
        print(f"已添加新成员:{new_member}")

def run_function1(members, lock):
    while True:
        function1(members, lock)
        time.sleep(2)

if __name__ == "__main__":
    members, lock = on_start()
    
    # 把字典和锁传给线程
    threading.Thread(target=run_function1, args=(members, lock), daemon=True).start()
    
    # 模拟触发事件
    time.sleep(3)
    function2(members, lock, {'guy3':'9012'})
    time.sleep(3)
    function2(members, lock, {'guy4':'3456'})

优缺点:没有全局变量,代码更“纯粹”;但如果需要共享这个字典的函数很多,每次都要传递参数会很繁琐,适合小型脚本。


内容的提问来源于stack exchange,提问作者TermoZour

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 07:56:28