用户定义类上复制模块的默认行为

2024-03-07

When copy.copy https://docs.python.org/2/library/copy.html#copy.copy or copy.deepcopy https://docs.python.org/2/library/copy.html#copy.deepcopy在用户定义的类的实例上调用,该类没有__copy__ or __deepcopy__方法,Python 保证会发生什么?令人不安的是,官方文档在这个问题上没有明确说明。该函数是否总是只返回同一类的新实例,并带有原始对象的浅/深副本__dict__(或者任何等价的东西__slots__参与)? CPython、PyPy 等之间的行为是否有所不同? Python 2 和 3 之间的行为有何不同? (忽略旧式类。)什么使人们需要定义显式的__copy__/__deepcopy__方法而不是使用默认行为?

参考文献explicit(比隐含的更好!)需要权威的陈述。


从读到the copy模块的来源 https://hg.python.org/cpython/file/tip/Lib/copy.py,除其他文件外,我已确定以下内容:

  • When copy or deepcopy在用户定义的新样式类的实例上调用,该类没有__copy__方法并且尚未注册可调用对象copy_reg.pickle https://docs.python.org/2.7/library/copy_reg.html#copy_reg.pickle,实例的__reduce_ex__ https://docs.python.org/2.7/library/pickle.html#object.__reduce_ex__使用协议 2 调用方法。object定义了一个__reduce_ex__方法由所有未定义自己的新式类继承,因此每个实例都有一个__reduce_ex__.

  • __reduce_ex__ and __reduce__ https://docs.python.org/2.7/library/pickle.html#pickling-and-unpickling-extension-types返回可用于酸洗的值,以及copy模块使用这些来模拟 unpickle、创建并返回由原始对象的状态组成的新对象。此外,当使用deepcopy,对象的状态(具体来说,由返回的元组的第三个元素__reduce_ex__/__reduce__) 在将其应用于新对象之前会递归地进行深度复制。

  • 一些基本测试表明调用__reduce_ex__(2)在一个实例上x一个简单的用户定义类的返回(<function __newobj__>, (type(x),), x.__dict__, None, None)。在 Python 2 和 Python 3 中,如果类没有__setstate__方法,将copy然后模块将执行与以下等效的操作:

    callable, args, state, _, _ = x.__reduce_ex__(2)
    y = callable(*args)
    if deepcopying:
        state = deepcopy(state)
    y.__dict__.update(state)
    return y
    

所以看来默认行为copy用户定义类的实例上的函数确实是做有用且简单的事情,并使用原始对象状态的(可能是深层的)副本创建一个新对象。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

用户定义类上复制模块的默认行为 的相关文章

随机推荐