Python: Numpy __deepcopy__ TypeError

后端 未结 3 2049
灰色年华
灰色年华 2020-12-12 02:51

I\'m trying to use deepcopy on an ndarray, and the line looks like this:

foo = myArray.__deepcopy__()

I\'m getting:

TypeErr         


        
相关标签:
3条回答
  • 2020-12-12 03:14

    The copy module contains the documentation for __deepcopy__, and it is quite clear what the argument should be:

    In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__(). The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary.

    But if you're not implementing a customized deep-copyable class you generally don't need to bother about this, simply use copy.deepcopy:

    from copy import deepcopy
    import numpy as np
    arr = np.random.random((100, 100))
    deepcopy(arr)
    

    It will take care of the memo-dict without your intervention. Note: Most of the __*__ are designed that way, you generally don't and shouldn't call them directly. So like you use x in y instead of y.__contains__(x) you normally use copy.deepcopy(x) instead of x.__deepcopy__(dict()).

    0 讨论(0)
  • 2020-12-12 03:15

    The relevant code in copy is:

    def deepcopy(x, memo=None, _nil=[]):
        """Deep copy operation on arbitrary Python objects.
    
        See the module's __doc__ string for more info.
        """
    
        if memo is None:
            memo = {}
            ....
               copier = getattr(x, "__deepcopy__", None)
                if copier:
                    y = copier(memo)
    ...
    # If is its own copy, don't memoize.
    if y is not x:
        memo[d] = y
        _keep_alive(x, memo) # Make sure x lives at least as long as d
    return y
    

    So memo is a memoize dictionary, at least when used 'properly'

    So if I pass a dictionary as memo, it changes that:

    In [160]: dd={}
    In [161]: A2=copy.deepcopy(A,memo=dd)
    In [162]: dd
    Out[162]: 
    {2814755008: array([[[0, 1, 0, 0, 0, 0],
             [0, 0, 1, 0, 0, 1],
             [0, 0, 0, 1, 0, 1],
             [1, 0, 0, 0, 1, 0]],
    
            [[0, 0, 1, 0, 0, 0],
             [0, 0, 1, 1, 0, 0],
             [0, 0, 0, 0, 0, 0],
             [0, 0, 0, 0, 0, 0]]]), 2814808588: [array([[[0, 1, 0, 0, 0, 0],
              [0, 0, 1, 0, 0, 1],
              [0, 0, 0, 1, 0, 1],
              [1, 0, 0, 0, 1, 0]],
    
             [[0, 0, 1, 0, 0, 0],
              [0, 0, 1, 1, 0, 0],
              [0, 0, 0, 0, 0, 0],
              [0, 0, 0, 0, 0, 0]]])]}
    In [163]: id(A)
    Out[163]: 2814755008
    In [167]: id(dd[id(A)])
    Out[167]: 2814568472
    In [168]: id(A2)
    Out[168]: 2814568472
    

    The memo keeps a record of the copy. I don't know what the 2nd item is.

    And if I ask for another deep copy with the same memo, it gives the memoized array rather than a new copy.

    In [173]: A3=copy.deepcopy(A,memo=dd)
    In [174]: id(A2)
    Out[174]: 2814568472
    In [175]: id(A3)
    Out[175]: 2814568472
    

    If an array is object dtype, the deepcopy might make a difference. The memo certainly looks different.

    0 讨论(0)
  • 2020-12-12 03:28

    The special __deepcopy__ method takes a memo arg. You can pass an empty dict for this:

    foo = myArray.__deepcopy__({})
    
    0 讨论(0)
提交回复
热议问题