2015-09-20 4 views
0

Я новичок в Python. Из моих друзей я узнал, что в python параметр, передаваемый функции, похож на call-by-reference в C++. Но после некоторого тестирования с NumPy я увидел некоторые поведения, которые я не могу понять.Параметр функции в python и изменение значения

В качестве примера я сделал следующий код.

#!/usr/bin/python 

import numpy as np 

def InitArray(x): 
    x = np.arange(0, 5) 

def ChangeValue(x): 
    x[2] = 4 

def main(): 
    x = np.array([1, 2, 3]) 
    print x 
    InitArray(x) 
    print x 
    ChangeValue(x) 
    print x 

if __name__ == "__main__": 
    main() 

Мои ожидания после вызова InitArray, массив «х» должно быть изменено на np.array([0, 1, 2, 3, 4]), но оказывается, что это не так.

Но когда я вызываю ChangeValue (x), значение фактически изменяется. Итак, результат следующий.

[1 2 3] 
[1 2 3] 
[1 2 4] 

То, что я не понимаю, почему значение не стало [0, 1, 2, 3, 4] после вызова InitArray?

+0

Возможный дубликат [В Python, почему функция может изменять некоторые аргументы, воспринимаемые вызывающим, но не другие?] (Http://stackoverflow.com/questions/575196/in-python-why-can-a -функции-модификация-некоторые-аргументы, а воспринимаемое-бай-зе-вызывающего абонента) – Joel

ответ

3

Я всегда думаю об этом как о прохождении ссылки, но назначение в Python не похоже на назначение на других языках. Это просто связывает ссылку вместе с объектом. Но эта ссылка может быть отключена от этого объекта и привязана к другой.

Когда вы делаете:

def InitArray(x): 
    x = np.arange(0, 5) 

Вы подменой локальную переменную х в другое значение. Но вы могли бы мутировать его. Позвольте мне дать вам не-Numpy пример:

>>> def foo(x): 
...  x[3] = 4 
...  x = [5, 5, 5] 
... 
>>> x = [0] * 20 
>>> x 
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 
>>> foo(x) 
>>> x 
[0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] 

Оператор перекомпоновка подобен изменению то, что указатель указывает на в С.

0

В ChangeValue вы обращаетесь к x в определенный момент в памяти. Принимая во внимание, что с InitArray вы по существу уничтожаете x в локальной области действия и переназначая его внутри функции, а затем не возвращаете измененный x.

Смежные вопросы