首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >变量在函数中修改,并在不应该修改时返回修改。

变量在函数中修改,并在不应该修改时返回修改。
EN

Stack Overflow用户
提问于 2016-03-26 19:29:35
回答 3查看 39关注 0票数 0

我正在使用以下程序:

代码语言:javascript
复制
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()

它正在屏幕上打印以下内容:

代码语言:javascript
复制
FUNCTION BEGIN
orig: (156, 20)

orig: (156, 20)

orig: (618, 434)

new: (618, 434)

FUNCTION END

我不明白的是,为什么我的原始变量在调用一个函数时会被修改,而它不应该被修改,因为它在另一个函数中使用。

我永远不会看到线的起源:(618,434),因为这意味着我的变量校准已经被修改,即使它没有从函数返回。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-03-26 19:40:49

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

为了有一个实际的新副本,即可以使用copy包,并使用deepcopy函数。您应该更改的行是new_calibration的初始化,即:

代码语言:javascript
复制
new_calibration = copy.deepcopy(calibration)

这导致了原始变量的保留。

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

票数 0
EN

Stack Overflow用户

发布于 2016-03-26 19:34:12

代码中有以下语句:

代码语言:javascript
复制
new_calibration = calibration

这意味着如果您更改了new_calibration,您也在更改校准,这就是为什么这些更改反映在print语句中。

票数 0
EN

Stack Overflow用户

发布于 2016-03-26 19:37:41

new_calibration = calibration仅仅意味着new_calibration引用calibration引用的同一个对象。如果要复制,请使用dict.copy()方法:

代码语言:javascript
复制
new_calibration = calibration.copy()

而且,如果您要做的只是重新定义new_calibration = {},那么new_calibration是无用的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36239901

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档