Python: изменить глобальный список внутри функции

Вопрос:Прежде всего, я понимаю, что я могу использовать оператор global для доступа к глобальным переменным. Но каким-то образом мне удалось изменить глобальный список без global, как показано ниже: def func1(nums): nums = [4,5,6] nums = [1,2,3] func1(nums) print nums # print [1,2,3] def func2(nums): nums[0] = 4 nums[1] = 5 nums[2] = 6 nums =

Вопрос:

Прежде всего, я понимаю, что я могу использовать оператор global для доступа к глобальным переменным. Но каким-то образом мне удалось изменить глобальный список без global, как показано ниже:

def func1(nums): nums = [4,5,6] nums = [1,2,3] func1(nums) print nums # print [1,2,3] def func2(nums): nums[0] = 4 nums[1] = 5 nums[2] = 6 nums = [1,2,3] func2(nums) print nums # print [4,5,6]

После попытки func2 я понял, что всегда могу получить доступ к глобальному списку в функции, если я укажу индекс:

def func3(nums): nums[:] = [4,5,6] nums = [1,2,3] func3(nums) print nums # print [4,5,6]

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

Спасибо.

Ответ №1

Я понимаю, что я могу использовать глобальную инструкцию для доступа к глобальным переменным

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

Ответ №2

Это концепция, основанная на изменяемых и неизменяемых объектах в Python. В вашем случае, например:

a=[1,2] def myfn(): a=[3,4] print id(a) >>>id(a) 3065250924L >>>myfn() 3055359596

Ясно, что оба являются разными объектами. Сейчас:

a=[1,2] def myfn(): a[:] =[3,4] print id(a) >>>id(a) 3055358572 >>>myfn() 3055358572

Это означает, что это одна и та же переменная, используемая в локальной и глобальной области.

Ответ №3

В этом конкретном случае это происходит потому, что list являются изменяемыми.

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

Если вы попытаетесь сделать то же самое с tuple, это не сработает, поскольку они неизменяемы.

Способ избежать этого – предоставить копию списка функции, а не самому списку:

func2(list[:])

В то же время вы можете сделать это с помощью аргументов по умолчанию, где вы можете указать аргумент по умолчанию как [], и если вы тогда .append() что-то к нему, этот аргумент по умолчанию навсегда удерживает этот элемент внутри него для все будущие вызовы (если вы не удалите их каким-либо образом).

Ответ №4

  • 2 переменные nums различаются, и они указывают на один и тот же объект или на два разных объекта, хотя они имеют одинаковое имя.
  • когда вы вызываете func1(nums), означает, что вы передаете ссылку. Теперь 2 переменная nums указывает на тот же объект. (2 переменные, 1 объект)
  • когда вы назначаете в func1, внутренняя переменная nums будет указывать на новый объект, внешний объект остается неизменным (2 переменные, 2 объекта)
  • и когда вы вызываете print nums, тогда nums является внешней переменной,

Ответ №5

Есть два фактора для этого результата:

  1. Переменные – это просто имена, которые ссылаются на объекты
  2. Список изменчив

В func1, nums относится к новому объекту, потому что новый список будет создан. Поэтому global nums не затрагиваются.

В func2 модификация применяется к переданному объекту. Таким образом, global nums изменяются. Новый объект не создан, потому что list изменчив.

ссылка: https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python

Оцените статью
Добавить комментарий