Python 3.8.3中实例化空类为何对象相互关联?
问题根源:可变默认参数的经典“陷阱”
这个问题是Python里新手特别容易踩的坑——可变默认参数的初始化时机搞反了!
你在__init__里写了initFruits = {},但Python的默认参数不是每次调用__init__时才创建的,而是在函数定义的那一刻就已经固定了。也就是说,这个空字典{}是个唯一的对象,所有没传initFruits参数的trees实例,都会共享这同一个字典。
所以你创建marigold = trees()时,self.fruits指向了这个共享字典;之后创建riverdale = trees(),它的self.fruits还是指着同一个字典。本质上两个实例操作的是内存里同一个对象,自然会互相影响。
解决方案:让每个实例拥有独立的字典
有两种简单的方式可以解决这个问题,保证每个实例的fruits都是独立的:
方法一:用None做默认参数,在方法内生成新字典
class trees: def __init__(self, initFruits=None): # 没传参数就创建全新的空字典 if initFruits is None: self.fruits = {} else: # 用copy()创建传入字典的副本,避免外部修改影响实例内部 self.fruits = initFruits.copy() def printFruits(self): for f in self.fruits: print(f, self.fruits[f])
方法二:简洁写法,直接生成独立字典
class trees: def __init__(self, initFruits=None): # 有参数就转成新字典,没参数就创建空字典 self.fruits = dict(initFruits) if initFruits else {} def printFruits(self): for f in self.fruits: print(f, self.fruits[f])
现在再测试你的代码:
marigold = trees() marigold.fruits["apple"] = 3 marigold.printFruits() # 输出:apple 3 riverdale = trees() riverdale.printFruits() # 输出为空,符合预期 riverdale.fruits["orange"] = 5 marigold.printFruits() # 依旧输出:apple 3,两个实例彻底独立了!
内容的提问来源于stack exchange,提问作者sekwjlwf
相关产品推荐
相关产品推荐

