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

Python字典中datetime对象的异常行为原因咨询

为什么修改字典b的'end'时,字典a的'end'也同步变化?

这事儿其实和datetime没啥关系,核心是Python里可变对象的引用赋值逻辑在搞鬼,咱们拿你的代码和预期对比着说:

先看你预期正常的整数场景

你代码里的self.x = self.y,整数是Python里的不可变对象——意思是一旦创建就没法修改它的内部值,赋值操作其实是把self.y的数值(也就是2)复制了一份给self.x。所以后续你修改self.x的时候,只是给self.x重新绑定了一个新的整数对象,完全不会影响self.y,这和你预期的一致。

再看出问题的字典场景

而字典是可变对象,当你写b = a的时候,根本不是复制了一个新的字典给b,而是让变量b和a指向内存里同一个字典对象。打个比方:就像你给同一个房间装了两扇门,a是第一扇门的钥匙,b是第二扇门的钥匙——不管你用哪把钥匙进去修改房间里的东西,从另一扇门看进去,房间里的东西肯定是变的。

你每次执行b['end'] = b['end'] + datetime.timedelta(days=3),本质是在修改这个共享字典里的end值,a作为指向同一个字典的变量,自然会看到同样的变化。

怎么解决?让a和b变成独立的字典

如果你想让a和b是两个互不影响的字典,需要创建字典的副本,常用的方法有这几种:

  • 浅拷贝(适合你的场景,因为字典里的datetime是不可变对象):
    b = a.copy()
    # 或者用dict()构造器
    b = dict(a)
    
  • 字典推导式:
    b = {key: value for key, value in a.items()}
    
  • 如果字典里还有嵌套的可变对象(比如字典里套字典、列表),需要用深拷贝:
    import copy
    b = copy.deepcopy(a)
    

把你的代码里b = a换成上面任意一种方式,再运行就会发现修改b['end']时,a['end']再也不会跟着变了。


你的原代码:

import datetime

class TBD: 
    def __init__(self): 
        self.x = 1 
        self.y = 2 
        print(self.x, self.y) 
        self.run_it() 
    def run_it(self): 
        self.x = self.y 
        z = 0 
        a = {'start': datetime.datetime.now(), 'end': datetime.datetime.now() + datetime.timedelta(days=1)} 
        b = a  # 这里是引用赋值
        while z < 3: 
            self.x += 1 
            z += 1 
            b['end'] = b['end'] + datetime.timedelta(days=3) 
            print(b['end'], a['end']) 
            print('x=', self.x, 'y=', self.y)

TBD()

修改后的代码(用copy()):

import datetime

class TBD: 
    def __init__(self): 
        self.x = 1 
        self.y = 2 
        print(self.x, self.y) 
        self.run_it() 
    def run_it(self): 
        self.x = self.y 
        z = 0 
        a = {'start': datetime.datetime.now(), 'end': datetime.datetime.now() + datetime.timedelta(days=1)} 
        b = a.copy()  # 创建副本
        while z < 3: 
            self.x += 1 
            z += 1 
            b['end'] = b['end'] + datetime.timedelta(days=3) 
            print(b['end'], a['end']) 
            print('x=', self.x, 'y=', self.y)

TBD()

修改后的运行结果会是a['end']一直保持初始的日期,而b['end']每次增加3天,完全符合你的预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 07:20:10