Передача значений в Python [дубликат]

этот вопрос уже есть ответ здесь:

когда вы передаете коллекцию list, array в другую функцию в python, делает ли она ее копию или это просто указатель?

8 ответов


Python передает ссылки на объекты по значению.

Python передает ссылки на объекты значение (например, Java), и все в Python-это объектно. Этот звук просто, но тогда вы заметите, что некоторые типы данных проявляют характеристики pass-by-value, пока другие, похоже, ведут себя как проходная ссылка... в чем дело?

важно понимать mutable и неизменные объекты. Несколько объектов, как строки, кортежи, и чисел, неизменный. Изменяя их внутри функция/метод создаст новый экземпляр и исходный экземпляр вне функции / метода нет измененный. Другие объекты, такие как списки и словари изменчивы, которые означает, что вы можете изменить объект на месте. Поэтому, изменяя объект внутри функции/метода также измените исходный объект внешний.


дело в том, что вся концепция ссылки/значения не будет вписываться в python. Python не имеет "значения" переменной. Python имеет только объекты и имена, которые ссылаются на объекты.

поэтому, когда вы вызываете функцию и помещаете " имя " в скобки, например:

def func(x): # defines a function that takes an argument
    ... # do something here

func(myname) # calling the function

реальный объект, который myname передается указатель, а не имя myname . Внутри функции другое название (x) дается для ссылки на прошел тот же объект.

вы можете изменить объект внутри функции, если он является изменяемым, но вы не может изменить то, что внешнее имя указывает на. Точно так же, что происходит, когда вы делаете

anothername = myname

поэтому я могу ответить на ваш вопрос:

это "передать по значению", но все значения находятся только ссылки на объекты.


ответы здесь были полезны, но я нахожу необходимость продемонстрировать это тонкое различие, которое я не видел покрытым, которое я доказал себе с последующим экспериментом CL:

  1. только неизменяемый объект не может быть изменен в вызове функции. (ответы до сих пор говорили об этом...)
  2. но неизменяемый объект, содержащийся в изменяемом объекте, может быть повторно назначен в методе вызов.

' num ' здесь не изменяется, потому что это неизменяемый объект Number [поддерживает мою точку 1.]:

def incr_num(num):
    num += 1

num = 0

num
0

incr_num(num)

num
0

'list[0]' здесь также является неизменяемым объектом Number.

def incr_list(list):
    list[0] += 1

list = [0]

list[0]
0

incr_list(list)

list[0]
1

Итак, как " list[0]", будучи неизменяемым объектом числа, изменился (поддерживает мою точку 2.) в то время как в приведенном выше примере объект Number 'num' не сделал? неизменяемый объект Number 'list[0]' содержится в изменяемом объекте list 'list', в то время как "num"из 1-го примера-это просто объект non-contianed Number.

несмотря на благие намерения, я чувствую себя @Stephen Pape top-rated ответ (цитируется ниже), и некоторые другие подобные, не были полностью правильными (и это побудило меня написать этот ответ):

некоторые объекты, такие как строки, кортежи и числа, неизменяемы. Изменение их внутри функции / метода создаст новый экземпляр и исходный экземпляр вне функции / метода не измениться.

мой второй эксперимент кода выше показывает, что объект Number ('list[0]') изменяется внутри метода, а затем исходный экземпляр вне функции изменяется.


ссылка передается, но если параметр является неизменяемым объектом, изменение его в методе создаст новый экземпляр.


объект. Не копия, а ссылка на базовый объект.


Я бы также рекомендовал посмотреть на copy модуль:

документация Python для копирования

Это поможет вам понять основные проблемы, и как использовать его самостоятельно выполнить глубокую копию.


ссылки:

>>> x = [0,1,2,3]
>>> def foo(x_list):
    x_list[0] = 1


>>> foo(x)
>>> x
[1, 1, 2, 3]

Пожалуйста, позвольте мне привести скромный пример

def swap(a, b):
    x = a
    print id(x)
    print id(a)
    print id(b)
    a = b

    print id(a)
    b = x
    print id(b)
    a[0]= '20'




var1 = ['1','2','3','4']
var2 = ['5','6','7','8','9']
print id(var1)
print id(var2)

swap(var1, var2)

print id(var1)
print id(var2)
print var1
print var2

который дает следующий результат

28329344 var1 28331264 переменная2 28329344 x 28329344 a 28331264 b После a = b 28331264 a после b = x 28329344 b после возврата 28329344 вар1 28331264 переменная2 ['1', '2', '3', '4'] ['20', '6', '7', '8', '9']

сопоставление с адресами памяти 28329344 28331264 переменная1 переменная2 б икс После a=b ля После b=x си После a[0] = '20' [0] = '20' После возврата ['1','2','3','4'] ['20', '6', '7', '8', '9']