PyCharm中datetime.now()微秒重复致交易历史被覆盖的问题
解决PyCharm中datetime.now()微秒重复导致交易记录被覆盖的问题
嘿,我之前做类似项目时也碰到过一模一样的问题!咱们先弄明白为啥会这样:PyCharm的运行环境比IDLE高效得多,连续调用withdraw方法时,代码执行速度快到datetime.datetime.now()生成的时间戳(尤其是微秒部分)还没来得及变化,导致字典history的键重复,后面的交易直接覆盖了前面的。而IDLE执行代码的速度慢,每次调用之间的时间间隔足够让微秒值变化,所以不会有这个问题。
下面给你几个实用的解决方案,你可以根据需求选择:
1. 改用精度更高的时间戳(适合简单场景)
用time.time()代替datetime.datetime.now(),它返回的是从1970年开始的浮点型时间戳,精度能到纳秒级别,连续调用几乎不会重复。修改代码如下:
首先导入time模块:
import time
然后修改withdraw方法里的时间生成部分:
def withdraw(self,pin,value): if self.checkCode(pin): if value <= self.balance: current_time = time.time() # 替换为高精度时间戳 history.update({current_time:-value}) self.balance -= value print("Successfully withdrawn " + str(value) + " euros from your account.") else: print("Not enough balance") else: print("Wrong pin code.Try again.")
2. 使用唯一标识符作为字典键(适合必须用字典的场景)
如果一定要用字典存储交易记录,可以用uuid模块生成全局唯一的ID作为键,这样不管时间是否重复,键都是唯一的。
先导入uuid模块:
import uuid
然后修改withdraw方法:
def withdraw(self,pin,value): if self.checkCode(pin): if value <= self.balance: transaction_id = uuid.uuid4() # 生成唯一ID history.update({transaction_id: {"time": datetime.datetime.now(), "amount": -value}}) self.balance -= value print("Successfully withdrawn " + str(value) + " euros from your account.") else: print("Not enough balance") else: print("Wrong pin code.Try again.")
3. 把交易记录改成列表(最符合业务逻辑的方案)
其实从业务角度来说,交易记录本来就应该是有序的列表——同一时间完全可能有多笔交易,字典的键唯一性限制了这一点。所以更合理的做法是把history改成列表,每个元素是包含时间和金额的字典:
初始化history为列表:
history = []
然后修改withdraw方法:
def withdraw(self,pin,value): if self.checkCode(pin): if value <= self.balance: current_time = datetime.datetime.now() history.append({"time": current_time, "amount": -value}) # 添加到列表 self.balance -= value print("Successfully withdrawn " + str(value) + " euros from your account.") else: print("Not enough balance") else: print("Wrong pin code.Try again.")
这样不管调用速度多快,所有交易记录都会被保留,还能按顺序查看,完全避免了键覆盖的问题。
内容的提问来源于stack exchange,提问作者Jun Yong
相关产品推荐
相关产品推荐

