"Python函数能强制数据不可变吗?"

2024-04-26 14:55:39 发布

您现在位置:Python中文网/ 问答频道 /正文

假设我定义了一个list对象,并且只希望它在我定义的函数中是只读的。在C++中,您将使用const引用进行此操作。有没有办法用python函数做到这一点?在写“Pythic”代码时,这是否有意义,或者我只是试图错误地应用C++范式?你知道吗


Tags: 对象函数代码定义错误list意义办法
3条回答

改用tuple

>>> hash([1,2,3])
Traceback (most recent call last):
  File "<pyshell#7>", line 1, in <module>
    hash([1,2,3])
TypeError: unhashable type: 'list'
>>> hash((1,2,3))
2528502973977326415
>>> 

hash可以定义它是可变的还是不可变的,如果它是可变的,则会产生一个错误TypeError: unhashable type,例如lists,OTOH tuple将返回一些大的数字(在这种特殊情况下不需要关心),如果您想:

try:
    hash((1,2,3))
    print('Immutable object')
except:
    print('Mutable object')

输出:

Immutable object

如其他答案所述,使用tuple是最常见的方法。假设您从list实例开始,其他可能的策略包括:

  • 如果函数中列表的角色只是循环,则传递迭代器而不是列表本身-iterator = iter(my_list)。请注意,您只能在迭代器上循环一次;如果需要多次循环,则可以传递一个生成器,该生成器会重复生成iter(my_list)。你知道吗
  • 传递列表的副本而不是列表本身:new_list = my_list.copy()new_list = my_list[:]。由于内存消耗,对于非常大的列表,这可能不是一个好的策略。你知道吗

无论您选择哪种方法(甚至元组),请注意,这些方法都假定集合中的元素本身是不可变的,例如整数和字符串。如果元素是可变的,则可以对其进行变异(但不能替换):

>>> t = ([1], [1,2])
>>> t[0] = 6
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t[0][0] = 6
>>> t
([6], [1, 2])


>>> L = [[1], [1, 2]]
>>> for x in iter(L):
...     x[0] += 1
... 
>>> L
[[2], [2, 2]]

>>> L = [[1], [1, 2]]
>>> copy = L.copy()
>>> for x in copy:
...     x[0] += 1
... 
>>> L
[[2], [2, 2]]
>>> 

>>> copy[0] = 42
>>> copy
[42, [2, 2]]
>>> L
[[2], [2, 2]]

您可以通过使用copy.deepcopy来解决这个问题,但同样需要消耗内存。你知道吗

在Python中,所有的变量都是引用,因此拥有C的const等价物并不能真正起到任何作用。如果指向的对象是可变的,则可以对其进行变异;如果它是不可变的,则不能

但是,有些类型是可变的,有些是不可变的。列表是可变的,但元组不是。因此,如果将数据作为元组传递,则可以保证函数不能对其执行任何操作。你知道吗

使用C隐喻,整数列表有点像int[],整数元组是const int[]。当您将它们传递给函数时,传递的是const引用还是非const引用并不重要;重要的是它引用的东西是否是const。你知道吗

相关问题 更多 >