Python 访问函数中的数组元素时的全局范围
当我将一个值赋给数组时,变量的作用域仍然是局部的(请参见Python 访问函数中的数组元素时的全局范围,python,arrays,scope,Python,Arrays,Scope,当我将一个值赋给数组时,变量的作用域仍然是局部的(请参见loc())。 但是,如果访问数组的元素,作用域将变为全局(请参见glob()) 为什么会发生这种情况?如何在不全局修改数组的情况下局部修改数组的元素?我需要在函数中有一个循环,每次更改一个元素。简单解释一下: 无法更新函数内的全局变量,除非将其作为函数内的全局变量访问 但它可以修改 检查: import numpy as np M = np.array([1]) def loc(): global M M = 2
loc()
)。
但是,如果访问数组的元素,作用域将变为全局(请参见glob()
)
为什么会发生这种情况?如何在不全局修改数组的情况下局部修改数组的元素?我需要在函数中有一个循环,每次更改一个元素。简单解释一下:
import numpy as np
M = np.array([1])
def loc():
global M
M = 2
return 0
def glob():
M[0] = 3
return 0
loc()
print M
>>>2
你在这里混合了几种东西 首先,
M=2
创建一个名为M
的局部变量(您可以在locals()
中看到),并阻止您以后访问原始M
(虽然您没有这样做…但只是为了说明一点)。这有时被称为
其次,是一个可变的对象(与对象相反),对它的更改将反映在对它的任何引用中。glob
函数中的内容是对M
的引用
您可以将np.array
视为一个具有多个名称的内存块,如果您更改了它,那么无论您使用什么名称访问它,更改都会很明显M[0]
只是对该内存特定部分的引用。这反映了对象的“状态”
如果你想做以下事情:
M = np.array([1])
def example()
another_name_for_M = M
M = 2
another_name_for_M[0] = 2
您仍然会看到全局M
正在更改,但您正在使用一个新名称来访问它
如果您使用字符串
、元组
、冻结集
等,这些都是无法(轻松)更改的不可变对象,您将无法实际更改它们的状态
现在回答您的问题,如果您不想让函数改变数组,只需使用发送一个数组,而不是实际的数组:
import numpy as np
my_array = np.array([1])
def array_mutating_function(some_array):
some_array[0] = 1337
print some_array # prints [1337]
# send copy to prevent mutating the original array
array_mutating_function(np.copy(my_array))
print my_array # prints [1]
这将有效地使它在外部作用域上不可变,因为函数将不会有对它的引用,除非它在外部作用域上使用它的名称,这可能不是一个好主意
如果函数不应更改任何数组,请在函数内部移动要在其上制作的副本,无论发送的是什么数组,防止其更改发送给它的任何数组:
def array_mutating_function(some_array):
some_array = np.copy(some_array)
some_array[0] = 1337
loc()
的行为和“global”的添加是明确的。这个问题与glob()
的行为有关。例如,如果我在def中有一个循环,该怎么办:对于范围内的I(100):M[I]=I
你可以像这样对于范围内的I(len(M)):M[I]=I
得到M=[0,1,2…]
到len(N)
全局declaredIt实际上没有什么区别,因为这样你可以全局地改变M。我想你必须做一些事情,比如M1=M.copy();对于范围内的i(len(M)):M1[i]=i
谢谢!这一点现在清楚多了。因此,一个好的经验法则是在任何函数内处理数组的副本,例如M1=M.copy()…
def array_mutating_function(some_array):
some_array = np.copy(some_array)
some_array[0] = 1337