Python 变量在函数中修改,并在不应修改时返回modified

Python 变量在函数中修改,并在不应修改时返回modified,python,Python,我正在使用以下程序: 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(c

我正在使用以下程序:

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
我不明白的是,为什么调用一个函数时会修改我的原始变量,而不应该修改,因为它在另一个函数中使用


我永远不会看到orig:(618434)这一行,因为这意味着我的变量校准已被修改,即使它不是从函数返回的。

您的代码中有以下语句:

new_calibration = calibration

这意味着如果您更改新的校准,您也在更改校准,这就是为什么更改会反映在打印语句中。

new\u calibration=calibration
只是意味着
new\u calibration
引用的对象与
calibration
引用的对象相同。如果要复制,请使用
dict.copy()
方法:

new_calibration = calibration.copy()

另外,
new\u calibration={}
如果您要做的只是重新定义
new\u calibration

问题是,当您将现有字典分配给新变量时,新变量实际上指向同一对象。您基本上可以使用函数检查对象的地址。在本例中,
id(校准)
id(新校准)
,您将看到它们具有相同的地址。这就是为什么如果新词典被修改,原始词典也会被修改的原因

为了获得实际的新副本,即,您可以使用package,并使用
deepcopy
功能。您应该更改的行是
new\u calibration
的初始化,即:

new_calibration = copy.deepcopy(calibration)
这将导致保留原始变量

请注意,在问题的代码中,浅层副本也起作用,字典的元素也是如此,它是一个不可变的对象。浅复制和深复制的区别在于,前者创建一个新的复合对象,并在可能的情况下添加在复制对象中找到的引用,而后者递归地创建新对象。在这个问题中,如果字典中的每个元素都是由两个元素组成的列表,而不是元组,那么为了只修改列表中的一个值,同时将列表保留在原始字典中,则需要一个深度副本。
有关浅拷贝和深拷贝之间区别的更多信息,请参阅文档。

它根本不是拷贝,甚至不是浅拷贝;这只是对同一对象的另一个引用。@DanielRoseman你是对的,我修正了错误的解释。谢谢