我想这是那些无意中用python创建引用的人提出的一长串问题中的一个,但我有以下情况。我使用scipy minimize将数组顶行的和设置为5(作为示例)。你知道吗
class problem_test:
def __init__(self):
test_array = [[1,2,3,4,5,6,7],
[4,5,6,7,8,9,10]]
def set_top_row_to_five(x, array):
array[0] = array[0] + x
return abs(sum(array[0]) - 5)
adjustment = spo.minimize(set_top_row_to_five,0,args=(test_array))
print(test_array)
print(adjustment.x)
ptest = problem_test()
但是,优化正在改变原始数组(test_array
):
[array([-2.03, -1.03, -0.03, 0.97, 1.97, 2.97, 3.97]), [4, 5, 6, 7, 8, 9, 10]]
[-0.00000001]
我意识到我可以用deepcopy来解决这个问题,但是我很想知道为什么会发生这种情况,这样我就不会在将来做同样的事情了。你知道吗
提前谢谢!你知道吗
名称是对对象的引用。要观察的是对象(也是在参数中传递的)是自己修改的还是创建了一个新对象。例如:
鉴于:
或:
同样假设
l = [1, 2, 3]
:我们刚刚通过了
None
返回了我的list.reverse
方法,并反转了l
(原地)。但是:函数从
l
返回一个新的反转对象(初始化),该对象保持不变(注意:在这个示例中,内置的reversed
或切片当然更有意义)嵌套时,不能忘记,例如:
字典
d1
和d2
是两个不同的对象,但它们的k
项只是一个(和共享的)实例。这种情况下copy.deepcopy
可能会派上用场。你知道吗在传递对象时需要小心,以确保它们已被修改,或者按需要和预期使用了copy。在进行就地更改时返回
None
或类似的泛型值,并在处理副本时返回结果对象,这样函数/方法接口本身就可以提示意图是什么以及实际发生了什么。你知道吗当不可变对象(顾名思义)被“修改”时,实际上会创建一个新对象,并将其分配给一个新对象或返回到原始名称/引用:
但请注意,即使是不可变类型也可能包含对可变对象的引用。例如
l = [1, 2, 3]; t1 = (l,); t2 = t1
,可以t1[0].append(4)
。这种变化也会出现在t2[0]
(原因与上面的d1['k']
和d2['k']
相同),而这两个元组本身保持不变。你知道吗一个额外的警告(可能有问题)。定义默认参数值(使用可变类型)时,在调用函数而不传递对象时,该默认参数的行为类似于“静态”变量:
由于这通常不是人们乍一看所假定的行为,所以最好避免使用可变对象作为默认参数值。你知道吗
对于在所有实例之间共享一个对象的类属性,情况也类似:
在类似的示例中,请注意类不可变类型class属性的行为:
所有有趣的细节都可以在文档中找到:https://docs.python.org/3.6/reference/datamodel.html
相关问题 更多 >
编程相关推荐