Global Scope when accessing array element inside function

|▌冷眼眸甩不掉的悲伤 提交于 2020-01-06 12:50:17

问题


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.


回答1:


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



回答2:


SImply explaining.:

  1. cannot update a global varaible inside a funcion unless access it as global inside function.
  2. But it can modify

Check:

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


来源:https://stackoverflow.com/questions/28566563/global-scope-when-accessing-array-element-inside-function

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!