我正在使用以下程序:
def coordsRelToPoint(origin,point):
result = (int(origin[0]) - int(point[0]) , int(origin[1]) - int(point[1]))
return result
def initCoordsRelToStartBattle(calibration):
print ('FUNCTION BEGIN')
print ('orig: %s' % str(calibration['center']))
print ('')
new_calibration = {}
new_calibration = calibration
print ('orig: %s' % str(calibration['center']))
print ('')
new_calibration['center'] = coordsRelToPoint((774,454),calibration['center'])
print ('orig: %s' % str(calibration['center']))
print ('')
print ('new: %s' % str(new_calibration['center']))
print ('')
print ('FUNCTION END')
return new_calibration
def main():
calibration = {}
calibration['center'] = (156,20)
initCoordsRelToStartBattle(calibration)
if __name__ == "__main__":
main()
在屏幕上打印以下内容:
FUNCTION BEGIN
orig: (156, 20)
orig: (156, 20)
orig: (618, 434)
new: (618, 434)
FUNCTION END
我不明白为什么我的原始变量在调用函数时会被修改,因为它在另一个函数中被使用。
我永远不会看到原始行:(618,434)因为这意味着我的变量校准已被修改,即使它没有从函数返回。
答案 0 :(得分:0)
您的代码中包含以下语句:
new_calibration = calibration
这意味着如果您更改new_calibration,您也会更改校准,这就是更改反映在print语句中的原因。
答案 1 :(得分:0)
new_calibration = calibration
仅表示new_calibration
引用calibration
引用的同一对象。如果要复制,请使用dict.copy()
方法:
new_calibration = calibration.copy()
此外,如果您要做的只是重新定义new_calibration = {}
,new_calibration
将毫无用处。
答案 2 :(得分:0)
问题在于,当您将现有字典分配给新变量时,实际上新变量指向同一个对象。您可以使用id
函数基本检查对象的地址。在示例id(calibration)
和id(new_calibration)
中,您会看到它们具有相同的地址。这就是为什么如果修改新词典也会修改原始字典的原因。
为了拥有一个实际的新副本,即您可以使用copy
包,并使用deepcopy
功能。您应该更改的行是new_calibration
的初始化,即:
new_calibration = copy.deepcopy(calibration)
这导致保留原始变量。
请注意,在问题的代码中,浅拷贝也起作用,因为tuple
是字典的元素,它是一个不可变对象。浅拷贝和深拷贝之间的区别基本上是第一个创建一个新的复合对象,并在可能的情况下添加复制对象中找到的引用,而后者递归创建新对象。在问题中,如果在字典中每个元素都是两个元素的列表而不是元组,那么为了在保留原始字典中的列表的同时仅修改列表的单个值,则需要深层复制。
有关浅拷贝和深拷贝之间差异的更多信息,请参阅copy
文档。