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

如何创建Python字典内int、str值的引用实现修改同步?

问题背景

假设我们有如下字典:

some_dict = {
    "first": 11111,
    "second": {
        "second_1": 22222,
        "second_2": 232323,
        "second_3": 99999
    }
}

当我们把嵌套字典赋值给新变量时,变量持有的是该嵌套字典的引用:

ref = some_dict["second"]

此时修改原字典里嵌套字典的内部值,ref的内容会同步变化:

some_dict["second"]["second_1"] = "not a second_1"
print(ref)

执行输出结果为:

{'second_1': 'not a second_1', 'second_2': 232323, 'second_3': 99999}
核心疑问

如何对int、str这类基础类型的值创建同等效果的引用?预期实现效果如下:

ref = some_dict["second"]["second_1"]

some_dict["second"]["second_1"] = "not a second_1"
print(ref)

预期输出结果:

not a second_1
解答

首先明确Python的变量本质:Python中所有变量存储的都是对象的引用,不存在"值类型直接存储值"的逻辑,但int、str、tuple属于不可变对象,对这类对象的"修改"本质是让变量指向新的对象,而非修改原有对象本身。
之前嵌套字典能实现同步更新,是因为字典是可变对象:修改字典内部键值对时,字典对象本身没有被替换,只是内部内容发生变化,所有指向这个字典对象的引用都会感知到变化。但如果直接把some_dict["second"]["second_1"]赋值给ref,相当于ref直接指向了当时值为22222的int对象,后续给字典键重新赋值,只是让字典的这个键指向了新的字符串对象,和ref之前指向的旧int对象没有关联,自然不会同步。
Python语法层面不支持直接持有"某个容器内某个位置"的透明引用,要实现预期效果,不能直接存储静态值,需要保留取值路径、动态读取最新值,常见实现方案如下:

  • 方案1:保存父容器和访问路径,取值时动态读取
    这是最轻量的实现方式,不需要额外封装,只需要记录值所在的容器和对应的键,每次取值时从容器中动态获取即可:
    # 单层路径的简单实现
    ref_parent = some_dict["second"]
    ref_key = "second_1"
    
    some_dict["second"]["second_1"] = "not a second_1"
    print(ref_parent[ref_key])  # 输出:not a second_1
    
    如果访问路径较深,可以把完整路径存为元组,配合简单的取值函数实现:
    def get_ref(root, path):
        cur = root
        for k in path:
            cur = cur[k]
        return cur
    
    ref_root = some_dict
    ref_path = ("second", "second_1")
    
    some_dict["second"]["second_1"] = "not a second_1"
    print(get_ref(ref_root, ref_path))  # 输出:not a second_1
    
  • 方案2:用包装类封装取值逻辑
    如果希望ref可以像普通值一样直接打印、参与运算,可以自定义简单的包装类,内部保存父容器和键,重写输出、运算相关的魔法方法:
    class Ref:
        def __init__(self, container, key):
            self.container = container
            self.key = key
        def __repr__(self):
            return repr(self.container[self.key])
        # 可根据需要重写__add__、__eq__等运算方法适配int/str操作
    
    ref = Ref(some_dict["second"], "second_1")
    some_dict["second"]["second_1"] = "not a second_1"
    print(ref)  # 输出:not a second_1
    

注意:不存在完全透明的基础类型引用。哪怕是之前的字典引用场景,如果你直接给some_dict["second"]赋值一个全新的字典对象,原来的ref也不会同步变化,本质逻辑和基础类型完全一致:只要你替换了容器内存储的对象本身,而不是修改对象内部内容,旧的引用就不会感知到变化。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 09:21:35