Передача значений в Python
Когда вы передаете коллекцию типа list, array в другую функцию в python, делает ли она ее копию или это просто указатель?
Ответы
Ответ 1
Python передает ссылки на объекты по значению.
Python передает ссылки на объекты посредством (например, Java) и все в Python - это объект. Это звучит просто, но тогда вы заметите, что некоторые типы данных характеристики передачи по значению, в то время как другие, похоже, действуют как pass-by-reference... какая сделка?
Важно понимать изменчивый и неизменные объекты. Некоторые объекты, как строки, кортежи и числа, являются неизменный. Изменение их внутри Функция/метод создаст новый экземпляр и исходный экземпляр вне функции/метода нет изменилось. Другие объекты, например списки и словари являются изменяемыми, что означает, что вы можете изменить объект на месте. Поэтому, изменяя объект внутри функции/метода будет также изменить исходный объект снаружи.
Ответ 2
Thing is, вся концепция reference/value не будет вписываться в 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
Поэтому я могу ответить на ваш вопрос:
это "передать по значению", но все значения - это просто ссылки на объекты.
Ответ 3
Ответы здесь были полезны, но я нахожу необходимость продемонстрировать это прекрасное различие, которое я не видел, которое я доказал себе с последующим экспериментом CL:
- Постоянный объект ALONE НЕ МОЖЕТ быть изменен внутри вызова функции. (ответы до сих пор так много говорили).
- НО, неизменяемый объект, содержащийся в изменяемом объекте, может быть повторно назначен в вызове метода.
'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" не был? Список неизмененных номеров объектов [0] 'содержится в списке "список" изменяемого списка, а "num" из 1-го примера - это просто несвязанный объект Number.
Несмотря на то, что я хорошо преднамеренно, я считаю, что @Stephen Pape самый высокий рейтинг (приведенный ниже) и некоторые другие подобные, были не совсем правильными (и это мотивировано мне написать этот ответ):
Некоторые объекты, такие как строки, кортежи и числа, неизменяемы. Изменение их внутри функции/метода создаст новый экземпляр и исходный экземпляр вне функции/метода не изменяется.
В моем втором эксперименте кода показан объект Number ('list [0]'), который изменяется в рамках метода, а затем исходный экземпляр вне функции изменился.
Ответ 4
Ссылка передается, но если параметр является неизменным объектом, его модификация внутри метода создаст новый экземпляр.
Вот нить по теме.
Ответ 5
Объект передается. Не копия, а ссылка на базовый объект.
Ответ 6
Я также рекомендую посмотреть модуль copy
:
Документация Python для копирования
Это поможет вам понять основные проблемы и использовать их для выполнения своей собственной глубокой копии.
Ответ 7
По ссылке:
>>> x = [0,1,2,3]
>>> def foo(x_list):
x_list[0] = 1
>>> foo(x)
>>> x
[1, 1, 2, 3]
Ответ 8
Пожалуйста, дайте мне скромный пример
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
Икс
После a = b
После b = x
б
После того, как [0] = '20' [0] = '20'
После возвращения
['1', '2', '3', '4'] ['20', '6', '7', '8', '9']