Если мы немного изменим ваш код, мы можем использовать id
, чтобы увидеть, как ссылки изменяются (или не изменяются):
L1=[2]
L2=['a']
print("Before, L1:", L1, id(L1))
print("Before, L2:", L2, id(L2))
def f(a,b):
print("Inside, Before, a:", id(a))
print("Inside, Before, b:", id(b))
a[0] =[3] #Using index-based assignment
b = ['b'] #Direct assignment
print("Inside, After, a:", id(a))
print("Inside, After, b:", id(b))
#Pass L to f
f(L1,L2)
print("After, L1:", L1, id(L1))
print("After, L2:", L2, id(L2))
Вывод:
Before, L1: [2] 1870498294152 # L1
Before, L2: ['a'] 1870498294280 # L2
Inside, Before, a: 1870498294152 # L1
Inside, Before, b: 1870498294280 # L2
Inside, After, a: 1870498294152 # L1
Inside, After, b: 1870498239496 # Something different, not L2
After, L1: [[3]] 1870498294152 # L1
After, L2: ['a'] 1870498294280 # L2
Обратите внимание, что цифры сами по себе не значимы, кроме как для того, чтобы помочь различать ссылки на разные объекты.Выполнение этого самостоятельно (или если я запустил его снова) приведет к изменению идентификаторов.
С a
вы изменяете / изменяете a
, но не пытаетесь переназначить ссылку.Все в порядке.
С b
вы переназначаете ссылку.Это будет работать внутри функции (как показывает вызов печати «Inside, After, b:»), но это изменение не будет отражаться за пределами функции.b
будет восстановлено для ссылки на исходный объект, ['a']
.
Что касается , почему ...
означаетЯ не уверен, почему прямое назначение изменяет местоположение в памяти.
Внутри вашей функции a
и b
являются просто ссылками на объекты.Первоначально они ссылаются (на объекты, на которые ссылаются) L1
и L2
соответственно, потому что, вызывая f
, вы передаете ссылки на эти объекты.
a[0] = [3]
first dereferences a
(илиL1
в данном случае), затем индекс [0]
и устанавливает это значение.
Фактически, если вы посмотрите на id(a[0])
до и после этого вызова, то , что будетменять.a
список литературы.Попробуйте:
print(id(a[0])) # One thing
a[0] =[3] #Using index-based assignment
print(id(a[0])) # Something different
Это нормально.При выходе из функции L1
по-прежнему ссылается на объект, на который ссылается функция, используя a
, и его мутация с индексом 0 сохраняется.
При b = ['b']
вы переназначаете или перепривязываете b
к новому объекту.Старый объект все еще существует (для последующего использования вне функции).
Наконец, я часто использую термин «ссылка», но Python - это не просто язык «передачи по ссылке», , а имена переменных связаны с объектами .Во втором случае вы перепривязываете b
, теряя связь с первоначально указанным объектом L2
навсегда.