python - 更新元组中的列表

标签 python

<分区>

我只是在解释器中玩弄,遇到了一些我不明白的东西。当我创建一个以列表作为元素之一的元组,然后尝试更新该列表时,会发生一些奇怪的事情。例如,当我运行这个时:

tup = (1,2,3,[4,5])
tup[3] += [6]

我得到:

TypeError: 'tuple' object does not support item assignment

这正是我所期望的。然而,当我再次引用元组时,我得到:

>>> tup
(1, 2, 3, [4, 5, 6])

所以即使 python 抛出异常,列表实际上也已更新。这是如何运作的?我无法想象我真的想做这样的事情的场景,但我仍然想了解发生了什么。谢谢你。

最佳答案

这实际上记录在 Python docs 中.

编辑:这是一个摘要,因此这是一个更完整的答案。

  1. 当我们使用+=时,Python会调用item上的__iadd__魔术方法,然后在后续的item赋值中使用返回值。
  2. 对于列表,__iadd__ 相当于在列表上调用extend,然后返回列表。
  3. 因此,当我们调用tup[3] += [6]时,相当于:

    result = tup[3].__iadd__([6])
    tup[3] = result
    
  4. 从#2,我们可以确定这等同于:

    result = tup[3].extend([6])
    tup[3] = result
    
  5. 第一行成功地调用了列表的 extend,并且由于列表是可变的,所以它会更新。但是,后续赋值失败,因为元组是不可变的,并抛出错误。

关于python - 更新元组中的列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39069509/

相关文章:

python - 通过串行连接与打印机通信时出现噪音

python - 如何使局部变量(函数内部)成为全局变量

python - 在python中按天对时间戳字符串进行分组

python - 如何查看引用对象的所有变量?

python - 接受与关键字/标准库冲突的变量名约定

python - 上下文变量不会显示在 Django 模板中

python - 如何更改 Django REST Framework 中 RetrieveAPIView 中 lookup kwargs 字段的键?

python - 如何检测 UDP 套接字的关闭客户端?

python - 尝试将 if elif else 语句与 eval(input()) 函数一起使用

python - 如何从 Ruby 提交 Celery 任务