将对象传递给函数,但不能在Python中对其进行修改

问题描述

是否存在一种简单/优雅的方法将对象传递给函数,而该方法不允许其从该函数内部进行修改?例如,对于传递的数组,应该无法执行

array[2]=1 

并更改数组的外部版本。那是一个例子,但我正在寻找一种不仅适用于数组的解决方案。

我考虑过passing a copy,但这有点不雅致,因为它需要不断使用副本库,并且需要不断地计算复制对象的工作量。

不允许以某种方式将对象作为整个进行修改,因为我确实希望在给定功能之外对其进行修改

解决方法

简短的回答是“否”。总会有一种方法可以某种方式访问​​对象并对其进行更新。

尽管有一些方法可以阻止对象的突变。这里有一些。

传递一个不变的对象

如果某些数据不应在程序执行过程中传递到某个点,则应将其设为不可变对象。

my_data = []
populate_my_data(my_data) # this part of the code mutates 'my_data'

my_final_data = tuple(my_data)

由于my_final_data是一个元组,因此无法进行突变。请注意,my_final_data中包含的可变对象仍然可以被突变。

在对象上创建视图

您可以在对象上提供一个 view ,而不是传递对象本身。视图是一些实例,提供了读取对象但不更新对象的方法。

在这里,您可以在list上定义一个简单的视图。

class ListView:
    def __init__(self,data):
        self._data = data

    def __getitem__(self,item):
        return self._data[item]

上面提供了一个界面,用于使用__getitem__从列表中读取内容,但没有一个界面可以更新它。

my_list = [1,2,3]
my_list_view = ListView(my_list)

print(my_list_view[0]) # 1
my_list_view[0] = None # TypeError: 'ListView' object does not support item assignment

再一次,突变数据并不是完全不可能的,人们可以通过字段my_list_view._data访问它。不过,这种设计可以合理地明确地表明,list不应在该点发生突变。

,

在C ++中,有一个const address param选项,可以防止更改给定的对象,

string concatenate (const string& a,const string& b)
{
  return a+b;
}

但是,在python中没有这种用法。您应该使用copy来处理任务。