2015-02-18 4 views
1

У меня есть этот кусок кода в Python:Python: Передавать по ссылке модифицирует этот аргумент

def sortList(x): 
    x.sort() 
    print "Values inside the function: ", x 
    return 

mylist = [100,20,30]; 
sortList(mylist); 
print "Values outside the function: ", mylist 

Выход есть:

Values inside the function: [20, 30, 100] 
Values outside the function: [20, 30, 100] 

Теперь, вместо того, чтобы писать x.sort() если я напишите x=[1,2,3], тогда выход:

Values inside the function: [1, 2, 3] 
Values outside the function: [100, 20, 20] 

Так почему же значение массива «mylist» изменяется внутри функции? И это тоже, только когда я выполняю некоторую операцию над ним, а не когда я назначаю ему совершенно новое значение?

Спасибо!

+0

Стоит посмотреть на это, что связано: http://stackoverflow.com/questions/12797749/python-and-reference-passing-limitation?rq = 1 – EdChum

+0

Поскольку 'list.sort' является ** на месте **, изменяет объект и возвращает' None', тогда как 'x = [1, 2, 3]' присваивает имя 'x' ** полностью новый объект ** и вообще не влияет на «mylist». – jonrsharpe

ответ

1

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

И в вашем коде в первый раз из-за вас использовать sort() функцию и изменить x на месте, оно влияет на абонента и изменения х по всему миру! Но когда вы задаете новый объект x на самом деле вы создаете локальный переменная внутри функции, которая ссылается на ваш новый объект ([1, 2, 3]).

Таким образом, для избежания Мутабельном Аргумент Изменения вы можете передать копию вашей переменной функционировать:

mylist = [100,20,30]; 
sortList(mylist[:]); 
print "Values outside the function: ", mylist 

результат:

Values inside the function: [20, 30, 100] 
Values outside the function: [100, 20, 30] 

В качестве другого пути вы можете преобразовать ваш аргумент непреложный объект, который изменится на него, вызовет ошибку, в этом случае вы можете преобразовать свой список в кортеж:

mylist = [100,20,30]; 
sortList(tuple(mylist)); 
print "Values outside the function: ", mylist 

Traceback (most recent call last): 
    File "/home/bluebird/Desktop/try.py", line 7, in <module> 
    sortList(tuple(mylist)); 
    File "/home/bluebird/Desktop/try.py", line 2, in sortList 
    x.sort() 
AttributeError: 'tuple' object has no attribute 'sort' 
+3

Не могли бы вы немного позаботиться о своем письме, пожалуйста - как бы то ни было, это не имеет смысла. Кроме того, * * обозначает пунктуацию, отличную от '!'. – jonrsharpe

+0

@jonrsharpe yep..fixed! – Kasramvd

+0

@jonrsharpe добро пожаловать спасибо! для напоминания;) – Kasramvd

0

Это просто: python передает аргумент не по значению (то есть к копии), а по ссылке. Таким образом, внутри sortList вы манипулируете тем же самым списком, в котором вы проходите. По своему усмотрению разработчик может исправить это. Один из способов - использовать вместо этого вызов sorted, который дает вам отсортированную копию последовательности. Другие включают использование copy.copy или copy.deepcopy

1

Вы передаете значение объекта в свою функцию, затем вы изменяете этот объект. Это изменяет объект. Существует только один объект, Python не создает независимую копию объекта, когда вы передаете его в функцию.

Теперь, если присвоить совершенно другой объект в переменнойx, что ничего не к объекту, который был ранее в x делать. Он просто нарушает ссылку от x к этому объекту. Так как этот объект по-прежнему ссылается на mylist, он продолжает существовать просто отлично.

+0

Я понимаю, что вы сказали в первом параграфе. Но не следует ли применять такую ​​же логику, когда вы назначаете? Я имею в виду, что даже «назначение» - это «изменение объекта»? Пожалуйста, дайте мне знать, если я ошибаюсь где-то. – ss2025

+0

Переменные - это «заполнители» в алгоритме. Они содержат ценности. Переменная * является * не значением. '=' помещает значение в переменную, оно не изменяет значение, которое могло быть в нем ранее. – deceze

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