Локальная переменная непреднамеренно изменяется в Python

#python #pandas #function #dataframe #variables

#python #pandas #функция #фрейм данных #переменные

Вопрос:

У меня есть фрейм данных pandas «df», к которому я применяю несколько функций. Я не хочу изменять значения исходного фрейма данных. Все мои функции выглядят следующим образом:

 def func(x):
# do some stuff with x
return x

 y = func(x=df)
  

Я не ссылаюсь на переменную df внутри функции. Но переменная все равно изменяется. Может кто-нибудь объяснить мне, почему это так и как этого избежать?

Комментарии:

1. Python передается по ссылке. df является изменяемой. Вы передаете ссылку на df методу, который ее изменяет. Если вы хотите сохранить оригинал нетронутым, отправьте копию df

2. @rdas Это не тот случай, когда Python передается по ссылке. Python использует стратегию оценки, называемую вызовом путем совместного использования . Это не очень известное имя, и его иногда называют «вызов по назначению», или, если в сообществе Java, «вызов по значению, где все значения являются ссылками». Независимо от того, что вы хотите вызвать, это не вызов по ссылке. Отличительной особенностью вызова по ссылке здесь было бы то, что присваивания параметру будут видны вызывающей стороне , чего не происходит в Python

Ответ №1:

Отправьте глубокую копию фрейма данных

 y = func(x=df.copy())
  

Которая по умолчанию является deepcopy.

Комментарии:

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

2. @Mars не согласно документации , это произойдет. В нем говорится deep default is True

3. Хороший улов! Я забыл, что это был фрейм данных pandas. Функция copy() в Python по умолчанию является неглубокой. Упс!