Python запутанная функция ссылки

Может ли кто-нибудь объяснить мне, почему две функции ниже a и b ведут себя по-другому. Функция a изменяет names локально и b изменяет фактический объект.

Где я могу найти правильную документацию для этого поведения?

 def a(names): names = ['Fred', 'George', 'Bill'] def b(names): names.append('Bill') first_names = ['Fred', 'George'] print "before calling any function",first_names a(first_names) print "after calling a",first_names b(first_names) print "after calling b",first_names 

Вывод:

 before calling any function ['Fred', 'George'] after calling a ['Fred', 'George'] after calling b ['Fred', 'George', 'Bill'] 

Функция a создает новые локальные names переменных и присваивает им список ['Fred', 'George', 'Bill'] . Так что теперь это другая переменная из глобальных first_names , как вы уже узнали.

Вы можете прочитать об изменении списка внутри функции здесь .

Один из способов заставить функцию a вести себя так же, как функция b – сделать функцию модификатором :

 def a(names): names += ['Bill'] 

Или вы можете сделать чистую функцию:

 def c(names): new_list = names + ['Bill'] return new_list 

И назовите это:

 first_names = c(first_names) print first_names # ['Fred', 'George', 'Bill'] 

Чистая функция означает, что она не изменяет состояние программы, т. Е. Не имеет никаких побочных эффектов, таких как изменение глобальных переменных.

Присвоение параметра внутри функции не влияет на переданный аргумент. Это позволяет локальной переменной ссылаться на новый объект.

Пока list.append изменяет список на месте.

Если вы хотите изменить список внутри функции, вы можете использовать назначение среза:

 def a(names): names[:] = ['Fred', 'George', 'Bill']