Skip to main content
missing words
Source Link
tbrugere
  • 1.8k
  • 18
  • 27

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.


Here is a breakdown of how that function works:

deepcopy(x, memo=None)

  1. checks if x is in the memo. If it is, return the value associated to it.

  2. tries to work out the copying method, by, in that order

    1. looking for it in the _deepcopy_dispatch dictionary
    2. checking if x has a __deepcopy__ method, and using that
    3. checking if it can be reduced (see here). Ie if it can be pickled. If that is the case, it basically runs that, copies the reduced object, and then unpickles it.
  3. runs the found method to create a copy

  4. registers that copy in the memo.

(I am ellipsing over some details, read the code if you are interesting in them)

So to answer your questions (and others you may have):

    • Q: what happens when you override __deepcopy__
    • A: It is called at step 3, instead of the default (unless there was a method in the _deepcopy_dispatch dictionary, but itthat dictionary should only contain methods for basic types)
    • Q: when does the recursivity happen
    • A: It happens when your __deepcopy__ function is called. This one should recursively call deepcopy with the same memo dictionary
    • Q: Why does Antony Hatchkins' implementation register the instance in memo if deepcopy function also does it (step 4)
    • A: because deepcopy registers the object in memo at the very end, whereas to avoid infinite recursion, you need to register it before doing recursive calls

Note: For a simpler way to allow your custom classes to be copied, you can also implement the __gestate__ and __setstate__ methods, and relying on the fact that deepcopy falls back on pickling methods

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.


Here is a breakdown of how that function works:

deepcopy(x, memo=None)

  1. checks if x is in the memo. If it is, return the value associated to it.

  2. tries to work out the copying method, by, in that order

    1. looking for it in the _deepcopy_dispatch dictionary
    2. checking if x has a __deepcopy__ method, and using that
    3. checking if it can be reduced (see here). Ie if it can be pickled. If that is the case, it basically runs that, copies the reduced object, and then unpickles it.
  3. runs the found method to create a copy

  4. registers that copy in the memo.

(I am ellipsing over some details, read the code if you are interesting in them)

So to answer your questions (and others you may have):

    • Q: what happens when you override __deepcopy__
    • A: It is called at step 3, instead of (unless there was a method in the _deepcopy_dispatch dictionary, but it should only contain methods for basic types)
    • Q: when does the recursivity happen
    • A: It happens when your __deepcopy__ function is called. This one should recursively call deepcopy with the same memo dictionary
    • Q: Why does Antony Hatchkins' implementation register the instance in memo if deepcopy function also does it (step 4)
    • A: because deepcopy registers the object in memo at the very end, whereas to avoid infinite recursion, you need to register it before doing recursive calls

Note: For a simpler way to allow your custom classes to be copied, you can also implement the __gestate__ and __setstate__ methods, and relying on the fact that deepcopy falls back on pickling methods

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.


Here is a breakdown of how that function works:

deepcopy(x, memo=None)

  1. checks if x is in the memo. If it is, return the value associated to it.

  2. tries to work out the copying method, by, in that order

    1. looking for it in the _deepcopy_dispatch dictionary
    2. checking if x has a __deepcopy__ method, and using that
    3. checking if it can be reduced (see here). Ie if it can be pickled. If that is the case, it basically runs that, copies the reduced object, and then unpickles it.
  3. runs the found method to create a copy

  4. registers that copy in the memo.

(I am ellipsing over some details, read the code if you are interesting in them)

So to answer your questions (and others you may have):

    • Q: what happens when you override __deepcopy__
    • A: It is called at step 3, instead of the default (unless there was a method in the _deepcopy_dispatch dictionary, but that dictionary should only contain methods for basic types)
    • Q: when does the recursivity happen
    • A: It happens when your __deepcopy__ function is called. This one should recursively call deepcopy with the same memo dictionary
    • Q: Why does Antony Hatchkins' implementation register the instance in memo if deepcopy function also does it (step 4)
    • A: because deepcopy registers the object in memo at the very end, whereas to avoid infinite recursion, you need to register it before doing recursive calls

Note: For a simpler way to allow your custom classes to be copied, you can also implement the __gestate__ and __setstate__ methods, and relying on the fact that deepcopy falls back on pickling methods

added 297 characters in body
Source Link
tbrugere
  • 1.8k
  • 18
  • 27

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.


Here is a breakdown of how that function works:

deepcopy(x, memo=None)

  1. checks if x is in the memo. If it is, return the value associated to it.

  2. tries to work out the copying method, by, in that order

    1. looking for it in the _deepcopy_dispatch dictionary
    2. checking if x has a __deepcopy__ method, and using that
    3. checking if it can be reduced (see here). Ie if it can be pickled. If that is the case, it basically runs that, copies the reduced object, and then unpickles it.
  3. runs the found method to create a copy

  4. registers that copy in the memo.

(I am ellipsing over some details, read the code if you are interesting in them)

So to answer your questions (and others you may have):

    • Q: what happens when you override __deepcopy__
    • A: It is called at step 3, instead of (unless there was a method in the _deepcopy_dispatch dictionary, but it should only contain methods for basic types)
    • Q: when does the recursivity happen
    • A: It happens when your __deepcopy__ function is called. This one should recursively call deepcopy with the same memo dictionary
    • Q: Why does Antony Hatchkins' implementation register the instance in memo if deepcopy function also does it (step 4)
    • A: because deepcopy registers the object in memo at the very end, whereas to avoid infinite recursion, you need to register it before doing recursive calls

Note: For a simpler way to allow your custom classes to be copied, you can also implement the __gestate__ and __setstate__ methods, and relying on the fact that deepcopy falls back on pickling methods

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.


Here is a breakdown of how that function works:

deepcopy(x, memo=None)

  1. checks if x is in the memo. If it is, return the value associated to it.

  2. tries to work out the copying method, by, in that order

    1. looking for it in the _deepcopy_dispatch dictionary
    2. checking if x has a __deepcopy__ method, and using that
    3. checking if it can be reduced (see here). Ie if it can be pickled. If that is the case, it basically runs that, copies the reduced object, and then unpickles it.
  3. runs the found method to create a copy

  4. registers that copy in the memo.

(I am ellipsing over some details, read the code if you are interesting in them)

So to answer your questions (and others you may have):

    • Q: what happens when you override __deepcopy__
    • A: It is called at step 3, instead of (unless there was a method in the _deepcopy_dispatch dictionary, but it should only contain methods for basic types)
    • Q: when does the recursivity happen
    • A: It happens when your __deepcopy__ function is called. This one should recursively call deepcopy with the same memo dictionary
    • Q: Why does Antony Hatchkins' implementation register the instance in memo if deepcopy function also does it (step 4)
    • A: because deepcopy registers the object in memo at the very end, whereas to avoid infinite recursion, you need to register it before doing recursive calls

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.


Here is a breakdown of how that function works:

deepcopy(x, memo=None)

  1. checks if x is in the memo. If it is, return the value associated to it.

  2. tries to work out the copying method, by, in that order

    1. looking for it in the _deepcopy_dispatch dictionary
    2. checking if x has a __deepcopy__ method, and using that
    3. checking if it can be reduced (see here). Ie if it can be pickled. If that is the case, it basically runs that, copies the reduced object, and then unpickles it.
  3. runs the found method to create a copy

  4. registers that copy in the memo.

(I am ellipsing over some details, read the code if you are interesting in them)

So to answer your questions (and others you may have):

    • Q: what happens when you override __deepcopy__
    • A: It is called at step 3, instead of (unless there was a method in the _deepcopy_dispatch dictionary, but it should only contain methods for basic types)
    • Q: when does the recursivity happen
    • A: It happens when your __deepcopy__ function is called. This one should recursively call deepcopy with the same memo dictionary
    • Q: Why does Antony Hatchkins' implementation register the instance in memo if deepcopy function also does it (step 4)
    • A: because deepcopy registers the object in memo at the very end, whereas to avoid infinite recursion, you need to register it before doing recursive calls

Note: For a simpler way to allow your custom classes to be copied, you can also implement the __gestate__ and __setstate__ methods, and relying on the fact that deepcopy falls back on pickling methods

added a breackdown of the implementation of deepcopy
Source Link
tbrugere
  • 1.8k
  • 18
  • 27

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.


Here is a breakdown of how that function works:

deepcopy(x, memo=None)

  1. checks if x is in the memo. If it is, return the value associated to it.

  2. tries to work out the copying method, by, in that order

    1. looking for it in the _deepcopy_dispatch dictionary
    2. checking if x has a __deepcopy__ method, and using that
    3. checking if it can be reduced (see here). Ie if it can be pickled. If that is the case, it basically runs that, copies the reduced object, and then unpickles it.
  3. runs the found method to create a copy

  4. registers that copy in the memo.

(I am ellipsing over some details, read the code if you are interesting in them)

So to answer your questions (and others you may have):

    • Q: what happens when you override __deepcopy__
    • A: It is called at step 3, instead of (unless there was a method in the _deepcopy_dispatch dictionary, but it should only contain methods for basic types)
    • Q: when does the recursivity happen
    • A: It happens when your __deepcopy__ function is called. This one should recursively call deepcopy with the same memo dictionary
    • Q: Why does Antony Hatchkins' implementation register the instance in memo if deepcopy function also does it (step 4)
    • A: because deepcopy registers the object in memo at the very end, whereas to avoid infinite recursion, you need to register it before doing recursive calls

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.

The (reference) implementation for copy.deepcopy is here

As you can see, the firsts thing that function does is check for the instance in the memo, so no need to check in your own implementation.


Here is a breakdown of how that function works:

deepcopy(x, memo=None)

  1. checks if x is in the memo. If it is, return the value associated to it.

  2. tries to work out the copying method, by, in that order

    1. looking for it in the _deepcopy_dispatch dictionary
    2. checking if x has a __deepcopy__ method, and using that
    3. checking if it can be reduced (see here). Ie if it can be pickled. If that is the case, it basically runs that, copies the reduced object, and then unpickles it.
  3. runs the found method to create a copy

  4. registers that copy in the memo.

(I am ellipsing over some details, read the code if you are interesting in them)

So to answer your questions (and others you may have):

    • Q: what happens when you override __deepcopy__
    • A: It is called at step 3, instead of (unless there was a method in the _deepcopy_dispatch dictionary, but it should only contain methods for basic types)
    • Q: when does the recursivity happen
    • A: It happens when your __deepcopy__ function is called. This one should recursively call deepcopy with the same memo dictionary
    • Q: Why does Antony Hatchkins' implementation register the instance in memo if deepcopy function also does it (step 4)
    • A: because deepcopy registers the object in memo at the very end, whereas to avoid infinite recursion, you need to register it before doing recursive calls
added 12 characters in body
Source Link
tbrugere
  • 1.8k
  • 18
  • 27
Loading
Source Link
tbrugere
  • 1.8k
  • 18
  • 27
Loading