Python类变量与实例变量的差异及错误结果成因解析
问题:类变量与实例变量导致的稀疏向量点积错误
当将vecDict声明为Vector类的类变量(在__init__方法外初始化)时,计算稀疏向量点积会得到错误结果;而将其声明为实例变量(在__init__方法内初始化)则结果正确,恳请解释原因。
相关代码
class Vector: # vecDict = {} ## 此处定义为类变量会得到错误结果,与__init__内定义不同 def __init__(self, nums): """ :type nums: List[int] """ self.vecDict = {} for i in range(len(nums)): self.vecDict[i]=nums[i] def getDict(self): return self.vecDict # 返回两个稀疏向量的点积 def dotProduct(self, vec): print(vec.getDict()) print(vec.vecDict) """ :type vec: 'SparseVector' :rtype: int """ dotProd = 0 secDict = vec.getDict() for k in secDict: if k in self.vecDict: dotProd += (self.vecDict[k] * secDict[k]) return dotProd
实例化与调用方式
v1 = Vector(numsA) v2 = Vector(numsB) ans = v1.dotProduct(v2)
示例输入
numsA = [1,0,0,2,3] numsB = [0,3,0,4,0]
预期结果:8
原因解释
- 类变量的共享特性:在类级别定义的
vecDict = {}属于类变量,它是所有Vector实例共享的同一个字典对象,而非每个实例独有。 - 实例化时的覆盖问题:当创建
v1 = Vector(numsA)时,会修改这个共享字典,将numsA的键值对存入其中;随后创建v2 = Vector(numsB)时,又会清空并覆盖这个共享字典,存入numsB的键值对。最终v1和v2的vecDict指向的是同一个字典,内容都是numsB的数据。 - 实例变量的独立性:在
__init__方法内定义self.vecDict = {}时,这是实例变量,每个Vector实例都会生成属于自己的独立字典,各自存储自身的向量数据,实例之间不会互相干扰。
结合示例来看:用类变量时,v1的vecDict最终会被v2的初始化操作覆盖为numsB的内容,此时计算v1.dotProduct(v2)实际是用numsB和numsB计算点积,结果为0*0 + 3*3 + 0*0 +4*4 +0*0 = 25,与预期的8不符,这就是错误的根源。
内容的提问来源于stack exchange,提问作者Hemanth Gowda
相关产品推荐
相关产品推荐

