To get a fully independent copy of an object you can use the copy.deepcopy() function.

For more details about shallow and deep copying please refer to the other answers to this question and the nice explanation in this answer to a related question.

Answer from Sven Marnach on Stack Overflow
Top answer
1 of 4
346

To get a fully independent copy of an object you can use the copy.deepcopy() function.

For more details about shallow and deep copying please refer to the other answers to this question and the nice explanation in this answer to a related question.

2 of 4
177

How can I create a copy of an object in Python?

So, if I change values of the fields of the new object, the old object should not be affected by that.

You mean a mutable object then.

In Python 3, lists get a copy method (in 2, you'd use a slice to make a copy):

>>> a_list = list('abc')
>>> a_copy_of_a_list = a_list.copy()
>>> a_copy_of_a_list is a_list
False
>>> a_copy_of_a_list == a_list
True

Shallow Copies

Shallow copies are just copies of the outermost container.

list.copy is a shallow copy:

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]

You don't get a copy of the interior objects. They're the same object - so when they're mutated, the change shows up in both containers.

Deep copies

Deep copies are recursive copies of each interior object.

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]

Changes are not reflected in the original, only in the copy.

Immutable objects

Immutable objects do not usually need to be copied. In fact, if you try to, Python will just give you the original object:

>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'tuple' object has no attribute 'copy'

Tuples don't even have a copy method, so let's try it with a slice:

>>> tuple_copy_attempt = a_tuple[:]

But we see it's the same object:

>>> tuple_copy_attempt is a_tuple
True

Similarly for strings:

>>> s = 'abc'
>>> s0 = s[:]
>>> s == s0
True
>>> s is s0
True

and for frozensets, even though they have a copy method:

>>> a_frozenset = frozenset('abc')
>>> frozenset_copy_attempt = a_frozenset.copy()
>>> frozenset_copy_attempt is a_frozenset
True

When to copy immutable objects

Immutable objects should be copied if you need a mutable interior object copied.

>>> tuple_of_list = [],
>>> copy_of_tuple_of_list = tuple_of_list[:]
>>> copy_of_tuple_of_list[0].append('a')
>>> copy_of_tuple_of_list
(['a'],)
>>> tuple_of_list
(['a'],)
>>> deepcopy_of_tuple_of_list = copy.deepcopy(tuple_of_list)
>>> deepcopy_of_tuple_of_list[0].append('b')
>>> deepcopy_of_tuple_of_list
(['a', 'b'],)
>>> tuple_of_list
(['a'],)

As we can see, when the interior object of the copy is mutated, the original does not change.

Custom Objects

Custom objects usually store data in a __dict__ attribute or in __slots__ (a tuple-like memory structure.)

To make a copyable object, define __copy__ (for shallow copies) and/or __deepcopy__ (for deep copies).

from copy import copy, deepcopy

class Copyable:
    __slots__ = 'a', '__dict__'
    def __init__(self, a, b):
        self.a, self.b = a, b
    def __copy__(self):
        return type(self)(self.a, self.b)
    def __deepcopy__(self, memo): # memo is a dict of id's to copies
        id_self = id(self)        # memoization avoids unnecesary recursion
        _copy = memo.get(id_self)
        if _copy is None:
            _copy = type(self)(
                deepcopy(self.a, memo), 
                deepcopy(self.b, memo))
            memo[id_self] = _copy 
        return _copy

Note that deepcopy keeps a memoization dictionary of id(original) (or identity numbers) to copies. To enjoy good behavior with recursive data structures, make sure you haven't already made a copy, and if you have, return that.

So let's make an object:

>>> c1 = Copyable(1, [2])

And copy makes a shallow copy:

>>> c2 = copy(c1)
>>> c1 is c2
False
>>> c2.b.append(3)
>>> c1.b
[2, 3]

And deepcopy now makes a deep copy:

>>> c3 = deepcopy(c1)
>>> c3.b.append(4)
>>> c1.b
[2, 3]
🌐
Python Module of the Week
pymotw.com › 2 › copy
copy – Duplicate objects - Python Module of the Week
Now available for Python 3! Buy the book! ... The copy module includes 2 functions, copy() and deepcopy(), for duplicating existing objects. The shallow copy created by copy() is a new container populated with references to the contents of the original object.
Discussions

How to copy a class object in python - Stack Overflow
This is quite a simple question, however I cannot seem to figure out how to do it. I simply need to make a copy of a class object, for example: class Foo(): def __init__(self, nums): ... More on stackoverflow.com
🌐 stackoverflow.com
python - How to copy a class? - Stack Overflow
You also can't just deepcopy(cls.__dict__) on new style objects. I've done the following to solve this problem for what I'm doing. I'm certain someone determined enough could break this. But, it will work in more cases. Copyfrom copy import deepcopy from typing import TypeVar Cls = TypeVar('Cls') # This type hint is a dirty lie to make autocomplete and static # analyzers give more useful results. Crazy the stuff you can do # with python... def copy_class... More on stackoverflow.com
🌐 stackoverflow.com
metaprogramming - how to make a copy of a class in python? - Stack Overflow
Actually, both in Python 2 and Python 3, copying a class __dict__ will suffice. If you want mutable objects that are class attributes not to be shared, you should resort again to deepcopy. More on stackoverflow.com
🌐 stackoverflow.com
How to copy a Python class instance if deepcopy() does not work? - Stack Overflow
I would like to make a copy of a class instance in python. I tried copy.deepcopy but I get the error message: RuntimeError: Only Variables created explicitly by the user (graph leaves) support the deepcopy protocol at the moment ... class C(object): def __init__(self,a,b, **kwargs): self.a=a ... More on stackoverflow.com
🌐 stackoverflow.com
🌐
Python for the Lab
pythonforthelab.com › blog › deep-and-shallow-copies-of-objects
Deep and Shallow Copies of Objects | Python For The Lab
It is very important to point out that, if are worried about copying and deep copying of custom objects, you should understand what are mutable and immutable objects in Python, and what are hashable objects. When you have immutable data types, such as an integer or a string, all the discussion above doesn't work. If you change an immutable attribute in a class, that attribute in deep-copied objects will not change.
🌐
Python
docs.python.org › 3 › library › copy.html
copy — Shallow and deep copy operations
... This module does not copy types like module, method, stack trace, stack frame, file, socket, window, or any similar types. It does “copy” functions and classes (shallow and deeply), by returning the original object unchanged; this is ...
🌐
O'Reilly
oreilly.com › library › view › python-cookbook › 0596001673 › ch05s12.html
Making a Fast Copy of an Object - Python Cookbook [Book]
July 19, 2002 - When you need a copy, you explicitly ask for it, ideally with the copy.copy function, which knows how to copy built-in types, has reasonable defaults for your own objects, and lets you customize the copying process by defining a special method _ _copy_ _ in your own classes. If you want instances of a class to be noncopyable, you can define _ _copy_ _ and raise a TypeError there.
Authors: Alex MartelliDavid Ascher
Published: 2002
Pages: 608
🌐
The Python Coding Book
thepythoncodingbook.com › home › blog › shallow and deep copy in python and how to use __copy__()
Shallow and Deep Copy in Python and How to Use __copy__()
November 12, 2023 - In more complex classes, you may want to define both __copy__() and __deepcopy__() if you want to distinguish between shallow and deep copy in your Python program. Here’s a summary of the key points you covered in this article: You created copies of simple lists and other data structures ... You’re now ready to safely copy any object, knowing what to look out for if the object references other objects.
Find elsewhere
Top answer
1 of 2
2

The problem you're encountering is that looking up a method attribute on a Python 2 class creates an unbound method, it doesn't return the underlying raw function (on Python 3, unbound methods are abolished, and what you're attempting would work just fine). You need to bypass the descriptor protocol machinery that converts from function to unbound method. The easiest way is to use vars to grab the class's attribute dictionary directly:

# Make copy of A's attributes
Bvars = vars(A).copy()
# Modify the desired attribute
Bvars['a'] = 2
# Construct the new class from it
B = type('B', (object,), Bvars)

Equivalently, you could copy and initialize B in one step, then reassign B.a after:

# Still need to copy; can't initialize from the proxy type vars(SOMECLASS)
# returns to protect the class internals
B = type('B', (object,), vars(A).copy())
B.a = 2

Or for slightly non-idiomatic one-liner fun:

B = type('B', (object,), dict(vars(A), a=2))

Either way, when you're done:

B().foo()

will output:

2
10

as expected.

2 of 2
1

You may be trying to (1) create copies of classes for some reason for some real app: in that case, try using copy.deepcopy - it includes the mechanisms to copy classes. Just change the copy __name__ attribute afterwards if needed. Works both in Python 2 or Python 3.

(2) Trying to learn and understand about Python internal class organization: in that case, there is no reason to fight with Python 2, as some wrinkles there were fixed for Python 3.

In any case, if you try using dir for fetching a class attributes, you will end up with more than you want - as dir also retrieves the methods and attributes of all superclasses. So, even if your method is made to work (in Python 2 that means getting the .im_func attribute of retrieved unbound methods, to use as raw functions on creating a new class), your class would have more methods than the original one.

Actually, both in Python 2 and Python 3, copying a class __dict__ will suffice. If you want mutable objects that are class attributes not to be shared, you should resort again to deepcopy. In Python 3:

class A(object):
    b = []
    def foo(self):
      print(self.b)

from copy import deepcopy

def copy_class(cls, new_name):
   new_cls = type(new_name, cls.__bases__, deepcopy(A.__dict__))
   new_cls.__name__ = new_name
   return new_cls

In Python 2, it would work almost the same, but there is no convenient way to get the explicit bases of an existing class (i.e. __bases__ is not set). You can use __mro__ for the same effect. The only thing is that all ancestor classes are passed in a hardcoded order as bases of the new class, and in a complex hierarchy you could have differences between the behaviors of B descendants and A descendants if multiple-inheritance is used.

🌐
Real Python
realpython.com › python-copy
How to Copy Objects in Python: Shallow vs Deep Copy Explained – Real Python
1 week ago - Python’s copy module provides the copy() function for shallow copies and deepcopy() for deep copies. Custom classes can implement .__copy__() and .__deepcopy__() for specific copying behavior.
🌐
Programiz
programiz.com › python-programming › shallow-deep-copy
Python Shallow Copy and Deep Copy (With Examples)
We use the copy module of Python for shallow and deep copy operations. Suppose, you need to copy the compound list say x. For example: ... Here, the copy() return a shallow copy of x. Similarly, deepcopy() return a deep copy of x. A shallow copy creates a new object which stores the reference of the original elements.
🌐
Quora
quora.com › How-can-I-copy-a-class-in-Python-I-am-using-two-almost-identical-classes-to-make-my-characters-in-a-game-that-Im-developing-So-how-could-I-copy-the-second-class-and-modify-only-the-things-I-want-to-change
How to copy a class in Python? I am using two almost identical classes to make my characters in a game that I'm developing. So how could I copy the second class and modify only the things I want to change - Quora
Answer (1 of 5): Inheritance might be useful here, but be careful. I don’t know how you are organising your code, but this may well be a scenario (pun intended) where composition is preferable. For example, if your game has character classes (warrior, paladin, druid, mage, thief etc.) you ...
🌐
Reddit
reddit.com › r/learnpython › what's the best way to make an identical copy of a class instance?
r/learnpython on Reddit: What's the best way to make an identical copy of a class instance?
December 16, 2019 -

I need to make an identical copy of an object (with the same attributes) while making sure that the copied items aren't referenced by multiple instances of the class.

Right now I have a class:

def class SomeClass:
    def __init__(self, attr1, attr2, attr3, ...):
        self.attr1 = attr1
        self.attr2 = attr2
        self.attr3 = attr3 ...

And to copy the class, I do something like

import copy

class_instance = SomeClass(attr1, attr2, attr3, ...)

copy_attr1 = copy.deepcopy(class_instance.attr1)
copy_attr2 = copy.deepcopy(class_instance.attr2)
copy_attr3 = copy.deepcopy(class_instance.attr3)

class_instance_copy = SomeClass(copy_attr1, copy_attr2, copy_attr3, ...)

I can't use copy on the classes because some of the class methods are generators, which apparently can't be pickled. Each class has roughly 20 attributes, so copying each one line by line is a pain. I'm curious if there is an easier or suggested method of doing this.

🌐
McNeel Forum
discourse.mcneel.com › rhino developer
Python - DeepCopy of custom class instance - Rhino Developer - McNeel Forum
April 6, 2020 - Hi, I’m trying to make a deepCopy of a custom python class instance, but it is miserably failing. I suspect that I’m missing some basic theory here. Any help on understanding why is happening this? thanks!
🌐
Scaler
scaler.com › home › topics › copy in python
Copy in Python - Scaler Topics
May 8, 2024 - In this point class, we created a Point object with two variables, a and b. And we have created a __repr__ function for ease of access to the values of the objects. Now we're going to see how the copy() functions work on objects that we have created. ... In this case, our Point class uses immutable data types in python - the int and hence here, a shallow copy or a deep copy is the same.
🌐
TutorialsPoint
tutorialspoint.com › how-can-you-copy-objects-in-python
How Can You Copy Objects in Python?
Use copy.copy() for shallow copying when you need a new object but can share references to nested objects. Use copy.deepcopy() when you need complete independence between original and copied objects.