目前在使用python做开发,有一个多月了,但是对python的引用传递和值传递,理解的不是很清楚,前几天做一个单子,其中将一个参数作为初始化值传递给一个接口,结果出了bug。问题主要是这样的,客户端做一个界面,界面上面有三个框,主要是将候选字拖到里面,那么在服务端每个人都对应这样一个框,也就是需要保存这个三个框的状态,需要持久化数据。调用的接口的定义如下:

class MyCounter(object):
	def __init__(self, id):
		self.m_Data = {}
	
	#iSecond是数据持久化时间
	def Set(self,key, val, iSecond):
		self.Detele(key)
		data.m_Data[key] = (val, iSecond)
	
	def Query(self, key, val, default = 0):
		data = self.m_Data
		if data.has_key(key):
			return data[key][0]
		return default

	def Delete(self, key):
		if self.m_Data.has_key(key):
			del self.m_Data[key]

客户端打开界面的时候,我会发送该框的数据给他,这个时候调用了上面的接口

INIT_WORDS_TBLE = {1:0, 2:0, 3:0}
tempDict = user.counter.QUery("%s.wordsState" % self.hdName(), INIT_WORDS_TBL)
#发送tempDict中的数据到客户端

客户端拖数据到框(激活候选字)中,然后服务端,需要更新人身上的框数据wordsState

#i表示框的编号,j表示哪个字
def C2SActive(self, i, j):
	tempDict = user.counter.QUery("%s.wordsState" % self.hdName(), INIT_WORDS_TBL)
	tempDict[i] = j

问题就是出在这里,这个地方tempDIct是引用,这里如果修改那么,INIT_WORDS_TBL将被修改,所以这里可以如下修改:

tempDict = dict(tempDict)

为什么会这样:

变量与对象

Python 中一切皆为对象,数字是对象,列表是对象,函数也是对象,任何东西都是对象。而变量是对象的一个引用(又称为名字或者标签),对象的操作都是通过引用来完成的。例如,[]是一个空列表对象,变量 a 是该对象的一个引用

a = []
 a.append(1)

在 Python 中,「变量」更准确叫法是「名字」,赋值操作 = 就是把一个名字绑定到一个对象上。就像给对象添加一个标签。

a = 1

python函数怎么传引用参数 python引用参数传递_客户端


整数 1 赋值给变量 a 就相当于是在整数1上绑定了一个 a 标签。

a = 2

python函数怎么传引用参数 python引用参数传递_客户端_02


整数 2 赋值给变量 a,相当于把原来整数 1 身上的 a 标签撕掉,贴到整数 2 身上。

b = a

python函数怎么传引用参数 python引用参数传递_Data_03

有了解释,则可以知道
tempDict[i] = j
中的tempDict它是引用,他的地址跟之前传入的INIT_WORDS_TBL的地址是一致的,如果对他整体赋值,它的地址就会改变,而之前的地址仍然是之前的地址,两者之间的关联断了。这里还需要说明的是,元组的元素不可以更新,但是元组中的可变的元素可以更新,这里的元素是字典,属于可变。