【问题标题】:Pass an object to a function without it being modifiable in Python将对象传递给函数而不在 Python 中进行修改
【发布时间】:2020-08-18 14:35:41
【问题描述】:

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

array[2]=1 

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

我考虑过passing a copy,但这感觉有点不雅,因为它需要不断地使用复制库,并且需要不断地计算复制对象。

不能以某种方式使对象作为一个整体不可修改,因为我确实希望在给定函数之外对其进行修改。

【问题讨论】:

  • 如果您可以将一个不可变对象传递给一个函数,然后该函数尝试对其进行变异,您期望会发生什么?
  • 某种例外是最好的,其次是它仅在本地影响对象的副本。要么是一个解决方案。

标签: python python-3.x object scope


【解决方案1】:

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

虽然,有一些方法可以阻止对象的突变。这里有一些。

传递一个不可变对象

如果某些数据不应该在程序执行的某个时间点被更新,则应将其设为不可变对象。

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 中包含的可变对象仍然可以被改变。

在对象上创建视图

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

您可以通过以下方式在 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 不应在此时发生突变。

【讨论】:

    【解决方案2】:

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

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

    然而,在 python 中,没有这种用法的等价物。您应该使用copy 来处理任务。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-05
      • 1970-01-01
      • 1970-01-01
      • 2015-09-04
      • 1970-01-01
      • 2014-06-24
      • 2015-06-13
      • 2012-05-01
      相关资源
      最近更新 更多