Можно ли вернуть значение функции в переменную являющуюся аргументом этой функции?

a= 2
b = 3

def test(val):
   val += 2
   return val

test(a)
test (b)

print (a) #результат должен быть 4
print (b) #результат должен быть 5

Ответы (1 шт):

Автор решения: mrEvgenX

Передача аргументов в python работает также, как присваивание.

  • Если ты передаешь переменную изменяемого типа (list, set, dict) в функцию, функция получает ссылку на сам объект, с которым можно делать все, что душе будет угодно и после завершения функции в контексте вызова переменные будут хранить ссылки на уже измененный объект. Но если внутри функции перепривязать к локальной переменной ссылку на другой объект, контекст вызова ничего об этом не узнает, а после завершения функции, исходная переменная будет содержать ту же самую ссылку, какая была до вызова.

  • Если ты передаешь объект неизменяемого типа (int, float, str, tuple...) в функцию, ты по-прежнему не можешь перепривязать ссылку из контекста вызова функции, но и изменить сам объект у тебя тоже не получится.

Попробую это прояснить на примере из вопроса же:

int - неизменяемый тип

a = 2

def test(val):
   val += 2
   return val # в переменной val будет 4

test(a)
print(a) #результат будет 2

a - это ссылка на объект 2. При вызове test локальная переменная val тоже ссылается на этот объект. Когда мы делаем val += 2, или, то же самое, что val = val + 2, мы конструируем объект 4 и ссылку на него кладем в val.

Однако после выхода из функции ссылка a по-прежнему указывает на объект 2.

Как же можно, все-таки, добиться желаемого поведения?

Просто вернуть значение, ну это очевидно:

a = 2

def test(val):
   val += 2
   return val

a = test(a)

print(a) #результат будет 4

Вспомним "The zen of python" - явное лучше, чем неявное. Поэтому этот способ наиболее предпочтителен.

Но если, действительно, ну очень хочется избежать явного возврата значения из функции и изменять само значение прямо в теле функции, можно использовать ключевое слово global. Однако, это троянский конь в истинном смысле, неизвестно какие ошибки в программе он может породить. Здравствуйте бессонные ночи отладки. Не рекомендуется.

А еще можно обернуть значение в изменяемый тип данных - например, список:

a = [2]

def test(val):
   val[0] += 2

test(a)

print(a[0]) #результат будет 4

Но если каждый раз так писать? Выглядит громоздко, на мой взгляд.

Использованные ресурсы:

→ Ссылка