我正在使用以下程序:
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),因为这意味着我的变量校准已经被修改,即使它没有从函数返回。
发布于 2016-03-26 19:40:49
问题是,当将现有字典分配给新变量时,新变量实际上指向同一个对象。您基本上可以使用id函数检查对象的地址。在本例中,id(calibration)和id(new_calibration)与您将看到它们具有相同的地址。这就是为什么如果新字典也被修改了,原来的字典也会被修改。
为了有一个实际的新副本,即可以使用copy包,并使用deepcopy函数。您应该更改的行是new_calibration的初始化,即:
new_calibration = copy.deepcopy(calibration)这导致了原始变量的保留。
注意,在问题的代码中,浅拷贝也能工作,因为tuple是字典的元素,它是一个不可变的对象。浅拷贝和深拷贝之间的区别基本上是,第一个复制创建一个新的复合对象,并在可能的情况下添加复制对象中找到的引用,而后者递归地创建新对象。在这个问题中,如果在字典中每个元素是一个由两个元素组成的列表,而不是一个元组,那么为了在保留原始字典中的列表的同时只修改一个列表的单个值,就需要一个深拷贝。有关浅拷贝和深拷贝之间区别的更多信息,请参阅copy文档。
发布于 2016-03-26 19:34:12
代码中有以下语句:
new_calibration = calibration这意味着如果您更改了new_calibration,您也在更改校准,这就是为什么这些更改反映在print语句中。
发布于 2016-03-26 19:37:41
new_calibration = calibration仅仅意味着new_calibration引用calibration引用的同一个对象。如果要复制,请使用dict.copy()方法:
new_calibration = calibration.copy()而且,如果您要做的只是重新定义new_calibration = {},那么new_calibration是无用的。
https://stackoverflow.com/questions/36239901
复制相似问题