【问题标题】:python modifies variable that is used as an argument of a function. How to prevent it properly? [duplicate]python 修改用作函数参数的变量。如何正确预防? [复制]
【发布时间】:2018-03-10 22:38:06
【问题描述】:

如果将变量用作函数的参数,则在函数内部使用参数进行的所有修改都将应用于该变量。 This is normal and expected,但在许多情况下是不可取的。防止这种行为的最佳做法是什么?示例:

import numpy as np
def func(A):
    for ind in range(A.shape[0]):  
        A[ind] = A[ind]+1
    return A

A = np.array([1, 2, 3])
NewA = func(A)
print(A)
print(NewA)

Out: [2, 3, 4]
Out: [2, 3, 4]

当我们想要的时候:

Out: [1, 2, 3]
Out: [2, 3, 4]

到目前为止,我只提出了两个想法。

方法一:显然,传递一个变量的副本:

A = np.array([1, 2, 3])
NewA = func(A.copy())
print(A)
print(NewA)
Out: [1, 2, 3]
Out: [2, 3, 4]

返回预期的结果,但当一个函数有 5 个参数时变得非常烦人:每次都键入 .copy() 太长了。

方法二: 修改函数体

def func(A):
    B = A.copy()
    for ind in range(B.shape[0]):  
        B[ind] = B[ind]+1
    return B

这同样令人讨厌,需要修改功能。 还有其他想法吗?

【问题讨论】:

  • 这应该不足为奇。请阅读this excellent blog post on python variables and values。您似乎缺少的关键点是您正在使用函数参数创建一个新变量,但该新变量引用的是相同的对象。因此,变量不会被修改,对象会被修改。
  • 感谢大家的回复。我修改了问题以突出建议的答案之间的区别。

标签: python numpy scientific-computing


【解决方案1】:

这是由于参数的类型。如果参数是不可变对象,例如intstring,则其作用类似于按值调用。如果它是一个可变对象,例如np.darray,它就像引用调用一样。

【讨论】:

  • 绝对不正确。无论对象的类型如何,Python 的评估策略总是相同的。请注意,intstr 都是对象。 Python 中的一切都是对象。
  • 同样,可变对象和不可变对象具有相同的评估策略,即既不按值调用也不按引用调用。您根本无法改变不可变对象,因此您永远看不到它们的任何更改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 2016-01-30
  • 1970-01-01
  • 2020-11-03
  • 2014-03-25
  • 1970-01-01
相关资源
最近更新 更多