【问题标题】:Will dict __getitem__ create a copy of the corresponding object?dict __getitem__ 会创建相应对象的副本吗?
【发布时间】:2014-02-27 15:42:03
【问题描述】:

我从here 看到了以下代码。

d[key] = data   # store data at key (overwrites old data if
                # using an existing key)
data = d[key]   # retrieve a COPY of data at key (raise KeyError if no
                # such key)

我不明白这样做的意义。据说retrieve a COPY of data at key。似乎 dict 查找(getitem,或索引,哪个是正确的术语?)会处理对象?对吧?

【问题讨论】:

    标签: python deep-copy


    【解决方案1】:

    您正在查看shelve 模块文档。

    shelve.open 返回一个类似字典的对象,而不是字典。它不会一次加载所有键值对;所以示例中的 cmets 是有意义的。

    【讨论】:

      【解决方案2】:

      通常,dict 查找返回存储在键中的值,而不是值的副本。这对于可变对象很重要。例如:

      A = dict()
      A["a"] = ["Hello", "world"] # Stores a 2-element list in the dict, at key "a"
      B = A["a"] # Gets the list that was just stored
      B[0] = "Goodbye" # Changes the first element of the list
      print(A["a"][0]) # Prints "Goodbye"
      

      相比之下,shelve 将返回与键一起存储的值的副本,因此更改返回的值不会更改搁置的值。

      【讨论】:

        【解决方案3】:

        您混淆了规范的实现(即 __getitem__ 对一种特定类型的对象所做的事情)(即对 __getitem__ 应该一直做的事情的规定)。

        __getitem__ 只是在x[i] 周围实现语法糖——它对实际完成的如何没有任何要求。 x[i] 可以在字典中返回与 i 关联的值。它可以返回一个副本。它可能会导致更多的副作用 - 即它可能会导致创建/删除文件、连接/断开数据库、创建/删除对象等。

        对于dict__getitem__ 被定义为返回原始对象。但是你不应该假设这些语义将适用于实现它的所有其他对象——你会失望的。如有疑问,您正在做正确的事情 - 检查文档。

        【讨论】:

        • 感谢您的回答,措辞清晰明确。我真正想知道的是关于内置类型dict实现
        • 好的,这更清楚了。如果你做mydict = {}; x = <something>; mydict['x'] = x,那么xmydict['x']指向同一个对象;它返回原始参考,而不是副本。另外,我应该指出这是“正常”行为——大多数对象实现__getitem__,它就像dict,并存储引用。在上面,shelve 以“粗体”提及 COPY 的一个原因是因为它不太常见,因此值得一提。
        猜你喜欢
        • 2016-08-08
        • 2023-03-22
        • 2020-03-03
        • 2015-02-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多