首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Python函数不应更改全局变量

Python函数不应更改全局变量
EN

Stack Overflow用户
提问于 2015-07-13 05:28:27
回答 3查看 722关注 0票数 3

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

据我所知,下面的代码通过修改一个全局变量而表现异常,尽管它不应该这样做。

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

输出为:

代码语言:javascript
运行
复制
[[0 1 2]
 [3 2 5]
 [6 7 8]]

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

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

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

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

输出为:

代码语言:javascript
运行
复制
[[0 1 2]
 [3 4 5]
 [6 7 8]]
EN

回答 3

Stack Overflow用户

发布于 2015-07-13 05:39:58

在第一种情况下

代码语言:javascript
运行
复制
def function(B):
    B[1,1] = B[1,1] / 2
    return B

修改名称B所指向的可变对象的特定元素的内容。正如在前面的回答中所描述的。

然而,在

代码语言:javascript
运行
复制
def function(B):
    B = B / 2
    return B

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

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

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

票数 3
EN

Stack Overflow用户

发布于 2015-07-13 06:03:25

与MATLAB不同,Python是一种pass by reference语言。通常,函数会被赋予对每个参数的引用。如果函数随后修改了一个参数,例如B[1,1]=...,则此更改将反映在参数中。

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

根据这个答案,MATLAB中的B(1,1) = B(1,1)/2会强制复制,这样B就不再与A共享引用。在Python中,这样的操作会修改调用参数,而不会进行复制。它是否出现在函数中并不重要。

票数 1
EN

Stack Overflow用户

发布于 2015-07-13 05:33:56

当您使用B[1,1] = B[1,1]/2时,您正在修改可变数据结构的元素--这会改变数据结构。在B = B / 2中,您正在重新分配本地作用域中的B,以指向其他对象。当您退出本地作用域时,该更改不会持久。

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

https://stackoverflow.com/questions/31372778

复制
相关文章

相似问题

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