Python函数不应该改变全局变量

时间:2015-07-12 21:28:27

标签: python function variables numpy global

我是Python和Numpy的新手,在将MATLAB程序翻译成Python时遇到了这个问题。

据我所知,下面的代码通过修改全局变量表现异常,即使它不应该。

import numpy as np

A = np.matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]])

def function(B):
    B[1,1] = B[1,1] / 2
    return B

C = function(A)

print(A)

输出结果为:

[[0 1 2]
 [3 2 5]
 [6 7 8]]

该函数将矩阵的中间数除以2并返回它。但它似乎也在改变全球变量。

在这里,问题很容易避免,但我试图理解它为什么会出现。

由于某些原因,如果函数将WHOLE矩阵除以2,则不会发生这种情况。

import numpy as np

A = np.matrix([[0, 1, 2], [3, 4, 5], [6, 7, 8]])

def function(B):
    B = B / 2
    return B

C = function(A)

print(A)

输出结果为:

[[0 1 2]
 [3 4 5]
 [6 7 8]]

3 个答案:

答案 0 :(得分:2)

在第一种情况下

def function(B):
    B[1,1] = B[1,1] / 2
    return B

更改名称B指向的可变对象的特定元素的内容。正如上一个答案所述。

然而,在

def function(B):
    B = B / 2
    return B

重点是B / 2是一个新对象。作为输入给出的对象不会改变。

您将其重新分配给本地名称B这一事实并不重要。它使B不再指向作为函数输入提供的原始对象,而是指向一个全新的对象实例。该函数返回。

因此,正确地,名称A指向的对象实例不受影响,即使是可变的。

答案 1 :(得分:1)

与MATLAB相比,Python是一种pass by reference语言。通常,函数被赋予对每个参数的引用。如果函数然后修改参数,例如B[1,1]=...,这一变化反映在论证中。

http://www.mathworks.com/matlabcentral/answers/152-can-matlab-pass-by-reference 是对MATLAB通过句柄v。按值传递参数的区别的解释。实际上,Python / numpy通过句柄传递。

根据这个答案,MATLAB中的B(1,1) = B(1,1)/2会强制复制,因此B不再与A共享引用。在Python中,此类操作会修改调用参数,而不会复制。它发生在函数中并不重要。

答案 2 :(得分:0)

当你有B[1,1] = B[1,1]/2时,你正在修改一个可变数据结构的元素 - 这会改变数据结构。在B = B / 2中,您将在本地范围内重新分配B以指向其他内容。退出本地范围时,该更改不会持续存在。