对象可变性:在本地环境中更改对象的副本会影响全局环境

时间:2017-03-15 11:16:32

标签: python immutability

import pandas as pd
import numpy as np
def my_fun(x):
    x[x>2] = 2
    y = 2 * x
    return y
sigma = pd.Series(np.linspace(0, 3, 80))
print(sigma.max())  # 3
my_fun(sigma)
print(sigma.max())  # 2

这里的问题是可变对象sigma的副本x在本地环境中发生了变化,影响了sigma本身。如何优雅地重写my_fun以避免更改可变对象sigma? my_fun的输入和输出必须是相同的类型。

2 个答案:

答案 0 :(得分:0)

您可以将句柄的副本传递给函数而不是实际对象的句柄。

my_fun(sigma.copy())

编辑:如果您担心忘记传递副本,可以将副本移动到该功能中。但是你必须假设对象x有一个.copy() - 函数,这可能会限制它的用途。

def my_fun(x_original):
    x = x_original.copy()
    x[x>2] = 2
    y = 2 * x
    return y

答案 1 :(得分:0)

只看my_func,你在那里做了三次操作。

a = x > 2
x[a] = 2
b = x * 2
  • 第一个创建一个新的布尔列表。这不会改变数组,而是使用新对象创建一个新列表。这意味着当您致电sigma.max()时,您将无法获得True

  • 第二行然后改变x - 你没有得到一个新阵列,你正在改变数据。 (问题)

  • 在第三行中,您将创建一个新列表,其中列表中的每个项目都会加倍。

因此您要创建一个新列表,然后改变数据。您可以通过先执行第三个操作来完成此操作。 所以你真的想要:

def my_fun(x):
    b = 2*x
    b[b>4] = 4
    return b