【问题标题】:Why does np.ndarray.__deepcopy__ require a superfluous argument? [duplicate]为什么 np.ndarray.__deepcopy__ 需要一个多余的参数? [复制]
【发布时间】:2017-08-02 13:47:57
【问题描述】:

副本将回答 what,但不会充分回答 why 或为什么文档中未提及它,即使它是必需的。继续阅读以了解更多...


有两种方法可以制作 numpy 数组的深拷贝。一种方法是使用copy 模块中的copy.deepcopy。另一种方式是直接拨打array.__deepcopy__

来自docs

ndarray.__deepcopy__() → Deep copy of array.

在数组上调用copy.deepcopy 时使用。

文档提示调用此函数的正确方法是不带任何参数。不过……

In [47]: x
Out[47]: 
array([[1, 1],
       [2, 2]])

In [48]: x.__deepcopy__()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-48-00c3b8eda618> in <module>()
----> 1 x.__deepcopy__()

TypeError: __deepcopy__() takes exactly 1 argument (0 given)

返回一个TypeError!但是……

In [51]: x.__deepcopy__(None)
Out[51]: 
array([[1, 1],
       [2, 2]])

甚至……

In [52]: x.__deepcopy__([12345, 'blah blah'])
Out[52]: 
array([[1, 1],
       [2, 2]])

看起来这个函数需要一个参数,但这个参数应该与返回的副本无关。

文档中未提及此参数。它是一个文档错误吗?为什么忽略了还要传入呢?

【问题讨论】:

    标签: python arrays numpy copy deep-copy


    【解决方案1】:

    Python 要求 __deepcopy__() 方法接受一个参数 memo (docs):

    为了让一个类定义自己的拷贝实现,它可以定义特殊方法__copy__()__deepcopy__()。前者被调用来实现浅拷贝操作;没有传递额外的参数。后者被调用来实现深拷贝操作; 传递一个参数,即备忘录字典。如果__deepcopy__() 实现需要对组件进行深拷贝,它应该调用deepcopy() 函数,将组件作为第一个参数,将备忘录字典作为第二个参数。

    它的目的是

    保留在当前复制过程中已复制的对象的“备忘录”字典

    如果对象包含引用循环,这可以防止在复制期间出现递归循环。

    我猜 numpy 不需要使用该参数,因为数组通常不包含对其他 Python 对象的递归引用,所以它被简单地忽略了。

    【讨论】:

    • 啊,很好。所以你会认为没有提及是一个文档错误?
    • 不,因为我认为您不应该在正常使用期间直接调用__whatever__ 函数。
    猜你喜欢
    • 2018-03-14
    • 2018-04-28
    • 2012-08-07
    • 1970-01-01
    • 2012-11-08
    • 1970-01-01
    • 2012-09-15
    • 2015-11-07
    • 1970-01-01
    相关资源
    最近更新 更多