Вопрос

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

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

Это было полезно?

Решение

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

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

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

Другие советы

Дело в том, что вся концепция ссылки / значения не будет вписываться в 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]', являющийся неизменяемым объектом Number, изменился (поддерживает мой пункт 2.), в то время как объект Number 'num' в приведенном выше примере этого не сделал? Неизменяемый объект Number 'list[0]' содержится в изменяемом объекте list 'список', в то время как 'num' из 1-го примера является просто несвязанным объектом Number.

Несмотря на благие намерения, я чувствую @Стивен Пейп ответ с самым высоким рейтингом (цитируется ниже) и некоторые другие подобные ответы были не совсем правильными (и это побудило меня написать этот ответ):

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

Мой 2-й эксперимент с кодом выше показывает, что объект 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 var2 28329344 x 28329344 a 28331264 b После a = b 28331264 a после b = x 28329344 b после возврата 28329344 var1 28331264 var2 ['1', '2', '3', '4'] ['20', '6', '7', '8', '9']

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top