访问函数内部的数组元素时的全局范围 [英] Global Scope when accessing array element inside function

查看:125
本文介绍了访问函数内部的数组元素时的全局范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我将值分配给数组时,变量的范围保持局部(请参见 loc())。
但是,如果我访问数组的元素,范围将变为全局(请参见 glob()

 导入numpy为np 
M = np.array([1])$ ​​b $ b def loc():
M = 2
返回0
def glob():
M [0] = 3
返回0

loc()
print M
> > [1]

glob()
print M
> [3]

为什么会这样?如何在不全局修改数组的情况下本地修改数组的元素?我的函数中需要有一个循环,一次只能更改一个元素。

解决方案

您在这里混合了几件事。 / p>

首先, M = 2 创建一个名为<$ c $的局部变量 c> M (您可以在 locals()中看到它),并阻止您访问原始的 M 稍后(尽管您没有这样做……只是为了提出一个要点)。有时被称为阴影



第二个是 np .array 是一个可变对象(与 不可变的对象 ),对其的更改将反映在对该对象的任何引用中。 glob 函数中的内容是对 M 的引用。



您可以将 np.array 视为具有许多名称的内存,如果更改了名称,无论使用什么名称,更改都将显而易见您正在使用它。 M [0] 只是对该内存特定部分的引用。这反映了对象的状态。



如果要执行以下操作:

  M = np.array([1])$ ​​b 
$ b def example()
another_name_for_M = M
M = 2
another_name_for_M [0] = 2

您仍然会看到全局 M 更改,但您使用的是新名称。



如果您使用字符串 tuple frozenset 等,它们都是不可变对象,不能(很容易)更改,您将无法实际更改其状态。



现在的问题是,如果您不希望函数仅改变数组的值发送副本,并使用 np.copy ,而不是实际的:

 将numpy导入为np 

my_array = np.array([1])$ ​​b
$ b def array_mutating_function(some_array):
some_array [0] = 1337
print some_array#打印[1337]

#发送副本以防止对原始数组进行变异
array_mutating_function(np.copy(my_array))
print my_array#打印[1]

这将有效地使其在外部范围内不可变,因为该函数除非在其上使用其名称,否则不会对其进行引用



如果函数永远不应该更改任何数组,则无论如何都应在函数内部移动副本发送数组,防止其更改发送给它的任何数组:

  def array_mutating_function(some_array):
some_array = np.copy(some_array)
some_array [0] = 1337


When I assign a value into an array the scope of the variable remain local (see loc()). However if I access the element of an array the scope becomes global ( see glob())

import numpy as np
M = np.array([1])
def loc():
    M = 2
    return 0
def glob():
    M[0] = 3
    return 0

loc()
print M
>>> [1]

glob()
print M
>>> [3]

Why does this happen ? How can i locally modify the elements of an array without modifying the array globally? I need to have a loop inside my function changing one element at a time.

解决方案

You're mixing several things here.

First of all, M = 2 creates a local variable named M (you can see it in locals()) and prevents you from accessing the original M later on (although you're not doing it... But just to make a point). That's sometimes referred to as "shadowing".

Second of all, the np.array is a mutable object (the opposite of an immutable object), and changes to it will reflect in any reference to it. What you have in your glob function is a reference to M.

You can look at an np.array as a piece of memory that has many names, and if you changed it, the changes will be evident no matter what name you're using to access it. M[0] is simply a reference to a specific part of this memory. This reflects the object's "state".

If you'd do something like:

M = np.array([1])

def example()
    another_name_for_M = M
    M = 2
    another_name_for_M[0] = 2

you would still see the global M changing, but you're using a new name to access it.

If you would use a string, a tuple, a frozenset and the likes, which are all immutable objects that can not be (easily) changed, you wouldn't be able to actually change their state.

Now to your question, if you don't want the function to mutate the array just send a copy of it using np.copy, and not the actual one:

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]

This will effectively make it immutable on the outer scope, since the function will not have a reference to it unless it's using it's name on the outer scope, which is probably not a good idea regardless.

If the function should never change any array, move the copy to be made on inside the function no matter what array is sent, preventing it from changing any array that was sent to it:

def array_mutating_function(some_array):
    some_array = np.copy(some_array)
    some_array[0] = 1337

这篇关于访问函数内部的数组元素时的全局范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆